dbms_stats能良好地估計統計數據(尤爲是針對較大的分區表),並能得到更好的統計結果,最終制定出速度更快的SQL執行計劃。
java
exec
dbms_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統計的刷新方式:web
gather——從新分析整個架構(Schema)。
gather empty——只分析目前尚未統計的表。
gather stale——只從新分析修改量超過10%的表(這些修改包括插入、更新和刪除)。
gather auto——從新分析當前沒有統計的對象,以及統計數據過時(變髒)的對象。注意,使用gather auto相似於組合使用gather stale和gather empty。
注意,不管gather stale仍是gather auto,都要求進行監視。若是你執行一個alter table xxx monitoring命令,Oracle會用dba_tab_modifications視圖來跟蹤發生變更的表。這樣一來,你就確切地知道,自從上一次分析統計數據以來,發生了多少次插入、更新和刪除操做。sql
estimate_percent選項
estimate_percent參數是一種比較新的設計,它容許Oracle的dbms_stats在收集統計數據時,自動估計要採樣的一個segment的最佳百分比:
estimate_percent => dbms_stats.auto_sample_size架構
要驗證自動統計採樣的準確性,你可檢視dba_tables sample_size列。一個有趣的地方是,在使用自動採樣時,Oracle會爲一個樣本尺寸選擇5到20的百分比。記住,統計數據質量越好,CBO作出的決定越好。
method_opt選項
method_opt:for table--只統計表
for all indexed columns--只統計有索引的表列
for all indexes--只分析統計相關索引
for all columnside
dbms_stats的method_opt參數尤爲適合在表和索引數據發生變化時刷新統計數據。method_opt參數也適合用於判斷哪些列須要直方圖(histograms)。
優化
某些狀況下,索引內的各個值的分佈會影響CBO是使用一個索引仍是執行一次全表掃描的決策。例如,假如在where子句中指定的值的數量不對稱,全表掃描就顯得比索引訪問更經濟。this
若是你有一個高度傾斜的索引(某些值的行數不對稱),就可建立Oracle直方圖統計。但在現實世界中,出現這種狀況的機率至關小。使用CBO時,最多見的錯誤之一就是在CBO統計中沒必要要地引入直方圖。根據經驗,只有在列值要求必須修改執行計劃時,才應使用直方圖。spa
爲了智能地生成直方圖,Oracle爲dbms_stats準備了method_opt參數。在method_opt子句中,還有一些重要的新選項,包括skewonly,repeat和auto:
method_opt=>'for all columns size skewonly'
method_opt=>'for all columns size repeat'
method_opt=>'for all columns size auto'.net
skewonly選項會耗費大量處理時間,由於它要檢查每一個索引中的每一個列的值的分佈狀況。設計
假如dbms_stat發現一個索引的各個列分佈得不均勻,就會爲那個索引建立直方圖,幫助基於代價的SQL優化器決定是進行索引訪問,仍是進行全表掃描訪問。例如,在一個索引中,假定有一個列在50%的行中,如清單B所示,那麼爲了檢索這些行,全表掃描的速度會快於索引掃描。
--
*************************************************************
--
SKEWONLY option—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
;
從新分析統計數據時,使用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=>’auto’相似於在dbms_stats的option參數中使用gather auto。
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
;
並行統計收集degree參數
Oracle推薦設置DBMS_STATS的DEGREE參數爲DBMS_STATS.AUTO_DEGREE,該參數容許Oracle根據對象的大小和並行性初始化參數的設置選擇恰當的並行度。
聚簇索引,域索引,位圖鏈接索引不能並行收集。
如何使用dbms_stats分析統計信息?
--建立統計信息歷史保留表
sql
>
exec
dbms_stats.create_stat_table(ownname
=>
'
scott
'
,stattab
=>
'
stat_table
'
) ;
--導出整個scheme的統計信息
sql
>
exec
dbms_stats.export_schema_stats(ownname
=>
'
scott
'
,stattab
=>
'
stat_table
'
) ;
--分析scheme
Exec
dbms_stats.gather_schema_stats(
ownname
=>
'
scott
'
,
options
=>
'
GATHER AUTO
'
,
estimate_percent
=>
dbms_stats.auto_sample_size,
method_opt
=>
'
for all indexed columns
'
,
degree
=>
6
)
--分析表
sql
>
exec
dbms_stats.gather_table_stats(ownname
=>
'
scott
'
,tabname
=>
'
work_list
'
,estimate_percent
=>
10
,method_opt
=>
'
for all indexed columns
'
) ;
--分析索引
SQL
>
exec
dbms_stats.gather_index_stats(ownname
=>
'
crm2
'
,indname
=>
'
IDX_ADM_PERMISSION_PID_MID
'
,estimate_percent
=>
'
10
'
,degree
=>
'
4
'
) ;
--若是發現執行計劃走錯,刪除表的統計信息
SQL
>
dbms_stats.delete_table_stats(ownname
=>
'
scott
'
,tabname
=>
'
work_list
'
) ;
--導入錶的歷史統計信息
sql
>
exec
dbms_stats.import_table_stats(ownname
=>
'
scott
'
,tabname
=>
'
work_list
'
,stattab
=>
'
stat_table
'
) ;
--若是進行分析後,大部分表的執行計劃都走錯,須要導回整個scheme的統計信息
sql
>
exec
dbms_stats.import_schema_stats(ownname
=>
'
scott
'
,stattab
=>
'
stat_table
'
);
--導入索引的統計信息