:2007.05.17 17:51
: oracle
http://zhouwf0726.itpub.net/post/9689/288301
---------------------------------------------------------------
dbms_statsԺOracleרҿͨһּķʽΪCBOռͳݡĿǰѾƼʹʽķdbms_utilityCBOͳݡЩϵķʽпΣSQLܣΪDzܹйرĸϢCBOʹöͳƣΪSQLѡѵִмƻ
dbms_statsõعͳݣԽϴķܻøõͳƽƶٶȸSQLִмƻ
±߸dbms_statsһʾִʹoptionsӾ䡣
execdbms_stats.gather_schema_stats( -
ownname => 'SCOTT', -
options => 'GATHER AUTO', -
estimate_percent => dbms_stats.auto_sample_size, -
method_opt => 'for all columns size repeat', -
degree => 15 -
)
Ϊ˳ʶdbms_statsĺôҪϸÿһҪԤָdirectiveоÿһָΪڴ۵SQLŻռͳݡ
options
ʹ4Ԥķ֮һѡܿOracleͳƵˢ·ʽ
- gather·ܹSchema
- gather emptyֻĿǰûͳƵı
- gather staleֻ·10%ıЩİ롢ºɾ
- gather auto·ǰûͳƵĶԼͳݹڣࣩĶע⣬ʹgather autoʹgather stalegather empty
ע⣬gather stalegather autoҪмӡִһalter table xxx monitoringOracledba_tab_modificationsͼٷ䶯ıһȷе֪Դһηͳ˶ٴβ롢ºɾ
estimate_percentѡ
estimate_percentһֱȽµƣOracledbms_statsռͳʱԶҪһsegmentѰٷֱȣ
estimate_percent => dbms_stats.auto_sample_size
Ҫ֤ԶͳƲȷԣɼdba_tables sample_sizeСһȤĵطǣʹԶʱOracleΪһߴѡ520İٷֱȡסͳԽãCBOľԽá
method_optѡ
dbms_statsmethod_optʺڱݷ仯ʱˢͳݡmethod_optҲʺжЩҪֱͼhistograms
ijЩ£ڵĸֵķֲӰCBOʹһִһȫɨľߡ磬whereӾֵָԳƣȫɨԵñʸá
һ߶бijЩֵԳƣͿɴOracleֱͼͳơʵУĻ൱СʹCBOʱĴ֮һCBOͳвҪֱͼݾ飬ֵֻҪִмƻʱӦʹֱͼ
ΪֱܵͼOracleΪdbms_statsmethod_optmethod_optӾУһЩҪѡskewonlyrepeatautomethod_opt=>'for all columns size skewonly'
method_opt=>'for all columns size repeat'
method_opt=>'for all columns size auto'
skewonlyѡķѴʱ䣬ΪҪÿеÿеֵķֲ
dbms_statһĸзֲòȣͻΪǸֱͼڴ۵SQLŻǽʣǽȫɨʡ磬һУٶһ50%У嵥BʾôΪ˼ЩУȫɨٶȻɨ衣--*************************************************************
-- SKEWONLY optionDetailed analysis
--
-- Use this method for a first-time analysis for skewed indexes
-- This runs a long time because all indexes are examined
--*************************************************************
begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size skewonly',
degree => 7
);
end;
·ͳʱʹrepeatѡ·ĵԴͻһЩʹrepeatѡ嵥CʱֻΪеֱͼ·ֱͼᡣ·ͳʱӦòȡַʽ--**************************************************************
-- REPEAT OPTION - Only reanalyze histograms for indexes
-- that have histograms
--
-- Following the initial analysis, the weekly analysis
-- job will use the repeat option. The repeat option
-- tells dbms_stats that no indexes have changed, and
-- it will only reanalyze histograms for
-- indexes that have histograms.
--**************************************************************begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size repeat',
degree => 7
);
end;
ʹalter table xxx monitoring;ʵOracleʱҪʹdbms_statsеautoѡ嵥DʾautoѡݷֲԼӦóеķʽͨӶȷһеĹֱͼʹmethod_opt=>autodbms_statsoptionʹgather autobegin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size auto',
degree => 7
);
end;
ռ
OracleԲзʽռCBOͳݣռͳݵٶȡǣҪ벢ռͳݣҪһ̨װ˶CPUSMP
ִٶ
dbms_statsSQLִٶȵһֳɫơͨʹdbms_statsռͳݣCBOܹȷжִκSQLѯʱ;dbms_statsڲϵظĽĿǰһЩ˼ԣԶСԶֱͼɣѾOracleרҵĹ
/*******************************************************/
One exciting feature of dbms_stats is the ability to automatically look for columns that should have histograms, and create the histograms. Multi-bucket histograms add a huge parsing overhead to SQL statements, and histograms should ONLY be used when the SQL will choose a different execution plan based upon the column value.
To aid in intelligent histogram generation, Oracle uses the method_opt parameter of dbms_stats. There are also important new options within the method_opt clause, namely skewonly, repeat and auto.
method_opt=>'for all columns size skewonly'
method_opt=>'for all columns size repeat'
method_opt=>'for all columns size auto'
In practice, there is a specific order to use the different options of dbms_stats. See this article for details. Lets take a close look at each method option.
The method_opt=SKEWONLY dbms_stats Option
The first is the skewonly option which very time-intensive because it examines the distribution of values for every column within every index. If dbms_stats discovers an index whose columns are unevenly distributed, it will create histograms for that index to aid the cost-based SQL optimizer in making a decision about index vs. full-table scan access. For example, if an index has one column that is in 50% of the rows, a full-table scan is faster than and index scan to retrieve these rows.
Histograms are also used with SQL that has bind variables and SQL with cursor_sharing enabled. In these cases, the CBO determines if the column value could affect the execution plan, and if so, replaced the bind variable with a literal and performs a hard parse.
--*************************************************************
-- SKEWONLY option C Detailed analysis
--
-- Use this method for a first-time analysis for skewed indexes
-- This runs a long time because all indexes are examined
--*************************************************************
begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size skewonly',
degree => 7
);
end;
/
The method_opt=REPEAT dbms_stats Option
Following the one-time detailed analysis, the re-analyze task will be less resource intensive with the REPEAT option. Using the repeat option will only re-analyze indexes with existing histograms, and will not search for other histograms opportunities. This is the way that you will re-analyze you statistics on a regular basis.
--**************************************************************
-- REPEAT OPTION - Only re-analyze histograms for indexes
-- that have histograms
--
-- Following the initial analysis, the weekly analysis
-- job will use the repeat option. The repeat option
-- tells dbms_stats that no indexes have changed, and
-- it will only re-analyze histograms for
-- indexes that have histograms.
--**************************************************************
begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size repeat',
degree => 7
);
end;
/
The method_opt=AUTO dbms_stats Option
The auto option is used when monitoring is implemented and creates histograms based upon data distribution and the manner in which the column is accessed by the application (e.g. the workload on the column as determined by monitoring, especially foreign keys to determine the cardinality of table join result sets). Using method_opt=>auto is similar to using the gather auto in the option parameter of dbms_stats.
begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size auto',
degree => 7
);
end;
/
Remember, analyzing for histograms is time-consuming, and histograms are used under two conditions:
Table join order C The CBO must know the size of the intermediate result sets (cardinality) to properly determine the correct join order the multi-table joins.
Table access method C The CBO needs to know about columns in SQL where clauses, where the column value is skewed such that a full-table scan might be faster than an index range scan. Oracle uses this skew information in conjunction with the clustering_factor columns of the dba_indexes view.
Hence, this is the proper order for using the dbms_stats package to locate proper columns for histograms:
1. Skewonly option - You want to use skewonly to do histograms for skewed columns, for cases where the value will make a difference between a full-table scan and an index scan.
2. Monitor - Next, turn-on monitoring. Issue an alter table xx monitoring and alter index yyy monitoring command for all segments in your schema. This will monitor workload against
3. Auto option - Once monitoring is in-place, you need to re-analyze with the "auto" option to create histograms for join columns within tables. This is critical for the CBO to determine the proper join order for finding the driving table in multi-table joins.
4. Repeat option - Finally, use the "repeat" option to re-analyze only the existing histograms.
Periodically you will want to re-run the skewonly and auto option to identify any new columns that require histograms. Once located, the repeat option will ensure that they are refreshed with current values.
--------------------------------------------------------------------------------
If you like DBA internal tricks, check-out my new book Creating a Self-tuning Oracle Database by Rampant TechPress. This book is now available at this link:
http://www.rampant-books.com/book_2...racle9i_sga.htm
Regards,
ȴһñ֮ǰķֵ
2 dbms_stats.create_stat_table(ownname => 'TEST',stattab => 'STAT_TABLE');
3 end;
4 /
PL/SQL ѳɹɡ
SQL> BEGIN
2 --DBMS_STATS.delete_table_stats(ownname => 'TEST',tabname => 'A');
3 DBMS_STATS.gather_table_stats(ownname => 'TEST',tabname => 'A');
4 END;
5 /
2 dbms_stats.export_table_stats(ownname => 'TEST',tabname => 'A',stattab => 'STAT_TABLE');
3 END;
4 /
ͬҲ
EXPORT_COLUMN_STATSеķϢ
EXPORT_INDEX_STATSϢ
EXPORT_SYSTEM_STATSϵͳϢ
EXPORT_TABLE_STATSϢ
EXPORT_SCHEMA_STATSϢ
EXPORT_DATABASE_STATSݿϢ
IMPORT_COLUMN_STATSзϢ
IMPORT_INDEX_STATSϢ
IMPORT_SYSTEM_STATSϵͳϢ
IMPORT_TABLE_STATSϢ
IMPORT_SCHEMA_STATS뷽Ϣ
IMPORT_DATABASE_STATSݿϢ
GATHER_INDEX_STATSϢ
GATHER_TABLE_STATSϢcascadeΪtrueʱУϢ
GATHER_SCHEMA_STATSϢ
GATHER_DATABASE_STATSݿϢ
GATHER_SYSTEM_STATSϵͳϢ
----------
1
ɾϢ
SQL> BEGIN
2 DBMS_STATS.delete_table_stats(ownname => 'TEST',tabname => 'A');
3 END;
4 /
Ϣ
SQL> BEGIN
2 DBMS_STATS.import_table_stats(ownname => 'TEST',tabname => 'A',stattab => 'STAT_TABLE');
3 END;
4 /
DBMS_STATS AND LEAF_BLOCKS
dbms_statsoracleԭеanalyzeܵһanalyzedbms_statsкܶƣ粢УϢͳƵȣdbms_statsٷindexʱʽ̫룬dbms_statsindexʱֻͳleaf_blocksΪǰݵleaf blockanalyzeͳΪʹùleaf block numberȻdbms_statsͳƽʹindex fast full scanijɱصijЩ»ѡindex fast full scanΪִ·һӣ
ԭı
SQL 10G>truncate table t1;
Table truncated.
SQL 10G>insert into t1 select
2 rownum id,
3 trunc(100 * dbms_random.normal) val,
4 rpad(x',100) padding
5 from
6 all_objects
7 where
8 rownum < = 10000
9 ;
10000 rows created.
SQL 10G>commit;
Commit complete.
pctfreeΪ99ģIJ
SQL 10G>create index ind_t1 on t1(id) pctfree 99;
Index created.
ʹanalyze
SQL 10G>ANALYZE INDEX IND_T1 COMPUTE STATISTICS;
Index analyzed.
SQL 10G>SELECT INDEX_NAME,BLEVEL,LEAF_BLOCKS FROM user_indexes where table_name=T1;
INDEX_NAME BLEVEL LEAF_BLOCKS
- C
IND_T1 2 10000
ʹdbms_statsԿʱͳͬ
SQL 10G>EXEC DBMS_STATS.GATHER_INDEX_STATS(TEST,'IND_T1);
PL/SQL procedure successfully completed.
SQL 10G>SELECT INDEX_NAME,BLEVEL,LEAF_BLOCKS FROM user_indexes where table_name=T1;
INDEX_NAME BLEVEL LEAF_BLOCKS
- C
IND_T1 2 10010
ɾʹֻһ¼
SQL 10G>delete from t1 where rownum<10000;
9999 rows deleted.
SQL 10G>commit;
Commit complete.
analyzeԷleaf_blocksȻ10000
SQL 10G>ANALYZE INDEX IND_T1 COMPUTE STATISTICS;
Index analyzed.
SQL 10G>SELECT INDEX_NAME,BLEVEL,LEAF_BLOCKS FROM user_indexes where table_name=T1;
INDEX_NAME BLEVEL LEAF_BLOCKS
- C
IND_T1 2 10000
costһʾindex fast full scanijɱΪ2679ȷ
SQL 10G>set autotrace trace exp;
SQL 10G>select/*+ index_ffs(t1,ind_t1)*/ count(*) from t1;
Execution Plan
-
| Id | Operation | Name | Rows | Cost (%CPU)|
-
| 0 | SELECT STATEMENT | | 1 | 2679 (19)|
| 1 | SORT AGGREGATE | | 1 | |
| 2 | INDEX FAST FULL SCAN| IND_T1 | 1 | 2679 (19)|
-
ʹdbms_statsleaf_blocksͳΪ1ֻͳ˵ǰõleaf block
SQL 10G>EXEC DBMS_STATS.GATHER_INDEX_STATS(TEST,'IND_T1);
PL/SQL procedure successfully completed.
SQL 10G>set autotrace off;
SQL 10G>SELECT INDEX_NAME,BLEVEL,LEAF_BLOCKS FROM user_indexes where table_name=T1;
INDEX_NAME BLEVEL LEAF_BLOCKS
- C
IND_T1 2 1
costһʾindex fast full scanijɱΪ1Ȼdz˴
SQL 10G>set autotrace trace;
SQL 10G>select/*+ index_ffs(t1,ind_t1)*/ count(*) from t1;
Execution Plan
-
| Id | Operation | Name | Rows | Cost (%CPU)|
-
| 0 | SELECT STATEMENT | | 1 | 1 (0)|
| 1 | SORT AGGREGATE | | 1 | |
| 2 | INDEX FAST FULL SCAN| IND_T1 | 1 | 1 (0)|
-
Ҫȡٸ飬Dzcost1
SQL 10G> ALTER SESSION SET EVENTS immediate trace name flush_cache;
Session altered.
SQL 10G>select/*+ index_ffs(t1,ind_t1)*/ count(*) from t1;
Execution Plan
-
-
| Id | Operation | Name | Rows | Cost (%CPU)|
-
| 0 | SELECT STATEMENT | | 1 | 1 (0)|
| 1 | SORT AGGREGATE | | 1 | |
| 2 | INDEX FAST FULL SCAN| IND_T1 | 1 | 1 (0)|
-
Statistics
-
0 recursive calls
0 db block gets
10035 consistent gets
10016 physical reads
0 redo size
411 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Ȼ10016physical readscost1ԶԶġ֪oracleиĽĿԴ






