如何收集及刪除列的統計信息

本文只涉及使用dbm_stats來收集或刪除列的統計信息的一些命令,以備查詢。

測試表如下(實驗環境爲10.2.0.4):

SQL> create table test(i int,a varchar2(30));
Table created.

SQL> insert into test select rownum,object_name from all_objects;
9907 rows created.

簡單的說,列的統計信息,主要包括兩種類型:

  • 只有基本信息:收集的統計信息只有1個桶(bucket)
  • 包含柱狀圖信息:收集的統計信息包含2到254個桶

也就是說,如果想收集列的基本信息,同時不希望收集柱狀圖,則需要指定bucket的size爲1:

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt=>'for columns i size 1');

PL/SQL procedure successfully completed.                                                                             

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,
avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN_NAM DISTINCT BUCKETS LOW_VALUE  HIGH_VALUE    DENSITY AVG_COL_LEN HISTOGRAM
---------- -------- ------- ---------- ---------- ---------- ----------- ----------
I              9907       1 C102       C26408     .000100939           4 NONE
A                                                                        NONE

如果要收集列的柱狀圖信息,則bucket的個數必須大於等於2(最多不超過254)

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt=>'for columns i size 2');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,
avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN DISTINCT BUCKETS LOW_VALUE HIGH_VALUE    DENSITY AVG_COL_LEN HISTOGRAM
------ -------- ------- --------- ---------- ---------- ----------- ---------------
I          9907       2 C102      C26408     .000100939           4 HEIGHT BALANCED
A                                                                   NONE

如果要刪除列已有的柱狀圖信息而保留列的基本統計信息,則需要重新收集bucket爲1的統計信息

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt=>'for columns i size 1');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,
avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN DISTINCT BUCKETS LOW_VALUE  HIGH_VALUE    DENSITY AVG_COL_LEN HISTOGRAM
------ -------- ------- ---------- ---------- ---------- ----------- ----------
I          9907       1 C102       C26408     .000100939           4 NONE
A                                                                    NONE

這個操作明顯不太合理,重新收集統計信息的代價有時候是很大的,所以Oracle11g對此做出了改進,允許只刪除柱狀圖而保留基本統計信息,命令語法如下:

exec dbms_stats.delete_column_stats(user, 'TEST','I',col_stat_type=>'HISTOGRAM');

而要徹底刪除整個列的統計信息,則需要調用delete_column_stats過程

SQL> exec dbms_stats.delete_column_stats(user, 'TEST', 'I');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,
avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN DISTINCT BUCKETS LOW_VALUE  HIGH_VALUE DENSITY  AVG_COL_LEN HISTOGRAM
------ -------- ------- ---------- ---------- -------  ----------- ----------
I                                                                  NONE
A                                                                  NONE

可以在同一個過程中收集多個列的統計信息,並且可以爲不同的列指定不同的bucket個數:

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt => 'for columns size 1 T for columns size 2 A');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,
avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN DISTINCT BUCKETS LOW_VALUE HIGH_VALUE              DENSITY AVG_COL_LEN HISTOGRAM
------ -------- ------- --------- -------------------- ---------- ----------- ---------------
I          9907       1 C102      C26408               .000100939           4 NONE
A          7376       2 41        5F75746C245F6C6E635F .000185239          18 HEIGHT BALANCED
                                  696E645F7061727473

值得注意的是,9i的dbms_stats中,method_opt的默認值是FOR ALL COLUMNS SIZE 1,也就是收集列的基本統計信息而不收集柱狀圖信息,而10g的默認值則變成了FOR ALL COLUMNS SIZE AUTO,則Oracle在收集列的基本信息之外,還會根據情況收集某些列的柱狀圖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章