
從10g開始,Oracle引入了自動收集統計量的作業,以保證資料字典中統計量正确反映資料對象狀态。這在很大程度上,緩解了由于資料變
在CBO時代,SQL語句的執行計劃完全依賴于在資料字典中儲存的統計量資訊和優化器Optimizer的計算公式參數。從9i開始到現在的11gR2,我們說CBO優化器已經很成熟和完善。在通常情況下,我們的SQL都是可以擷取到較好的執行計劃以及執行效率的。
在實際工作中,我們經常會遇到執行計劃低效的情況。但是這種故障根源中,絕大多數的原因在于統計量的錯誤或者失效。錯誤的統計量連帶生成的就是不恰當的執行計劃,以至于低效的執行過程。在9i時代,RBO和CBO混合使用,讓我們經常需要自定義的統計量收集過程。
從10g開始,Oracle引入了自動收集統計量的作業,以保證資料字典中統計量正确反映資料對象狀态。這在很大程度上,緩解了由于資料變化導緻的統計量過期問題。但是,我們在實際工作中,還是會發現執行計劃的突然變化。究其原因,就是某個時間點收集的統計量,也許不能反映資料的全貌(如中間表)。
1、統計量Pending
在系統運維中,我們常常希望維持SQL執行計劃的穩定。很多DBA和開發人員對于hint的依賴,很大程度上也是源于對CBO情況下,執行計劃對于統計量過于依賴,容易形成不穩定執行計劃。
那麼,我們SQL語句執行計劃的穩定性,就變成統計量的穩定性問題。更進一步,就是新的統計量更新,無論是否手動收集還是自動收集,能否促進SQL語句生成更高效的執行計劃。
是以,一種思路是:在新的統計量收集生成時,暫時不要生效投入執行計劃生成。等待最後确認統計量正确之後,再投入生産環境。
在Oracle 11g中,推出了統計量管理的一種新技術——Pending Statistic技術,提供了這種功能。
簡單的說,我們可以對一系列的資料表設定pending屬性。設定pending屬性之後,資料的統計量在資料字典中相當于已經鎖定Lock住。但新統計量生成之後,不是直接替換原有的資料,而是存放在pending資料字典中。
在pending字典中的統計量,預設情況下是不會參與SQL執行計劃的生産的。隻有在進行SQL測試通過的時候,經過使用者手工的确定,才會将其Publish出來,替換原有的統計量資訊。
這樣,就給我們運維DBA一種維持執行計劃穩定的思路。通過固定統計量,将新統計量pending的方式将原有的統計量固定,進而穩定執行計劃。進而,對pending的統計量進行測試,隻有在更好執行計劃的情況下,才會替換原有的方案。
下面,我們通過實驗來驗證pending統計量的使用。
2、實驗環境建構
我們選擇11gR2進行實驗。
SQL> select * from v$version;
BANNER
-----------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
建構資料表T,以及對應的索引。注意,我們首先在資料表中不儲存任何資料。
SQL> create table t as select * from dba_objects where 1=0;
Table created
SQL> create index idx_t_owner on t(owner);
Index created
SQL> create index idx_t_id on t(object_id);
Index created
在不顯式的收集統計量的情況下,,是沒有對應的資料表統計量的。
SQL> select NUM_ROWS, BLOCKS EMPTY_BLOCKS, AVG_SPACE, CHAIN_CNT, AVG_ROW_LEN from user_tab_statistics where table_name='T';
NUM_ROWS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ------------ ---------- ---------- -----------
SQL> select count(*) from user_tab_col_statistics where table_name='T';
COUNT(*)
----------
SQL> select BLEVEL, LEAF_BLOCKS, DISTINCT_KEYS, CLUSTERING_FACTOR NUM_ROWS from user_ind_statistics where index_name='IDX_T_OWNER';
BLEVEL LEAF_BLOCKS DISTINCT_KEYS NUM_ROWS
---------- ----------- ------------- ----------
0 0 0 0
收集統計量,擷取最新的資料分布狀況。
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);
PL/SQL procedure successfully completed
當我們修改資料内容,沒有收集統計量,會存在新舊差異。
SQL> insert into t select * from dba_objects;
72202 rows inserted
SQL> commit;
Commit complete
SQL> select NUM_ROWS, BLOCKS EMPTY_BLOCKS, AVG_SPACE, CHAIN_CNT, AVG_ROW_LEN from user_tab_statistics where table_name='T';
NUM_ROWS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ------------ ---------- ---------- -----------
0 0 0 0 0

本條技術文章來源于網際網路,如果無意侵犯您的權益請點選此處回報版權投訴
本文系統來源:php中文網