When you use dbms_stats.gather_schema_stats package with cascade=>true option, you are also collecting stats for the indexes, no need to collects stats separately using dbms_stats.gather_index_stats.
Of course, but I refered to the rebuild index question. Therefore I only mentioned the GATHER_INDEX_STATS.
Auto_sample_size has many problems/bugs in 9i
Ok didn't know that - I'm using 10gR2.
But this discussion made me curious. So I tried something (10gR2):
CREATE TABLE BIG NOLOGGING AS
WITH GEN AS (
SELECT ROWNUM ID FROM ALL_OBJECTS WHERE ROWNUM <=10000)
SELECT V1.ID,RPAD('A',10) C FROM GEN V1,GEN V2
WHERE ROWNUM <=10000000;
SELECT COUNT(*) FROM BIG;
COUNT(*)
----------
10000000
So I had a Table containing 10 Million rows. Now I indexed ID:
CREATE INDEX BIG_IDX ON BIG(ID)
I tested two different methods:
1.) GATHER_TABLE_STATS with estimate 10%
EXEC DBMS_STATS.GATHER_TABLE_STATS(TABNAME=>'BIG',OWNNAME=>'DIMITRI',CASCADE=>TRUE,ESTIMATE_PERCENT=>10);
It took about 6 seconds (I only set timing on in sqlplus, no 10046 trace) Now I checked the estimated values:
SELECT NUM_ROWS,SAMPLE_SIZE,ABS(10000000-NUM_ROWS)/100000 VARIANCE,'TABLE' OBJECT FROM USER_TABLES WHERE TABLE_NAME='BIG'
UNION ALL
SELECT NUM_ROWS,SAMPLE_SIZE,ABS(10000000-NUM_ROWS)/100000 VARIANCE,'INDEX' OBJECT FROM USER_INDEXES WHERE INDEX_NAME='BIG_IDX';
NUM_ROWS SAMPLE_SIZE VARIANCE OBJEC
---------- ----------- ---------- -----
9985220 998522 ,1478 TABLE
9996210 999621 ,0379 INDEX
2.) GATHER_TABLE_STATS with DBMS_STATS.AUTO_SAMPLE_SIZE
EXEC DBMS_STATS.DELETE_TABLE_STATS(OWNNAME=>'DIMITRI',TABNAME=>'BIG');
EXEC DBMS_STATS.GATHER_TABLE_STATS(TABNAME=>'BIG',OWNNAME=>'DIMITRI',CASCADE=>TRUE,ESTIMATE_PERCENT=>DBMS_STATS.AUTO_SAMPLE_SIZE);
It took about 1,5 seconds. Now the results:
NUM_ROWS SAMPLE_SIZE VARIANCE OBJEC
---------- ----------- ---------- -----
9826851 4715 1,73149 TABLE
10262432 561326 2,62432 INDEX
The estimate 10% was more exact - also a 1,7 and 2,6 percent variance is still ok. It's also very interesting, that using AUTO_SAMPLE_SIZE
causes oracle to execute a estimate 5% for the index and a estimate 0.5 for the table.
I tried again with a table containing only 1 Million records and oracle did an estimate with 100% for the index.
So for me I will continue using AUTO_SAMPLE_SIZE. Its very flexible, fast and accurate.
Dim
PS: Is there a way to format code like one can do in HTML using <code> or <pre>?