♣ 程序員
題目 部分面試
在Oracle中,如何收集直方圖信息?在收集直方圖時有哪些注意事項?數據庫
♣ 微信
答案部分
網絡
默認狀況下,數據庫會爲列收集基本統計信息,但不會收集直方圖信息。Oracle經過指定DBMS_STATS的METHOD_OPT參數來建立直方圖。METHOD_OPT參數能夠接受以下的輸入值:ide
1FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause] 2FOR COLUMNS [size_clause] column|attribute [size_clause] [,column|attribute [size_clause]...]
其中的size_clause必須符合以下的格式:學習
1SIZE {integer | REPEAT | AUTO | SKEWONLY}
含義以下所示:url
l SKEWONLY:只對數據分佈不均衡的列收集直方圖統計信息。.net
l REPEAT:只對己經有直方圖統計信息的列收集直方圖統計信息。3d
l AUTO:讓Oracle自行決定是否對目標列收集直方圖統計信息,以及使用哪一種類型的直方圖。
l integer:直方圖的Bucket的數量,必須是在1~254的範圍內,1表示刪除該目標列上的直方圖統計信息。
METHOD_OPT參數的默認值爲「FOR ALL COLUMNS SIZE AUTO」,「FOR ALL COLUMNS SIZE 1」表示刪除全部列直方圖統計信息。下面是一些經常使用的收集方法:
l 對T表上全部有索引的列以自動收集的方式收集直方圖:FOR ALL INDEXED COLUMNS SIZE AUTO
l 對T表上的列A和列B以自動收集的方式收集直方圖:FOR COLUMNS SIZE AUTO A B
l 對T表上的列A和列B收集直方圖統計信息,同時指定BUCKET數量均爲10:FOR COLUMNS SIZE 10 A B
l 對T表上的列A和列B收集直方圖統計信息,同時指定列A的BUCKET數量爲10,列B的BUCKET數量爲5:FOR COLUMNS A SIZE 10 B SIZE 5
l 只刪除表T上列A的直方圖統計信息:FOR COLUMNS A SIZE 1
l 刪除表T上全部列的直方圖統計信息:FOR ALL COLUMNS SIZE 1
若是須要刪除某個列SAL的直方圖信息,在Oracle 10g中能夠經過設置「METHOD_OPT=>'FOR COLUMNS SAL SIZE 1'」,但這卻得再次收集表的統計信息,十分不合理,因此,在Oracle 11g中,有以下方法能夠直接刪除直方圖信息:
1EXEC DBMS_STATS.DELETE_COLUMN_STATS(USER,'T_ST_20170604_LHR','SAL',COL_STAT_TYPE => 'HISTOGRAM');
其中,COL_STAT_TYPE默認爲ALL,表示刪除列的基本統計信息和直方圖信息。
SKEWONLY的示例以下:
1BEGIN 2 DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => '', 3 TABNAME => '', 4 ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE, 5 METHOD_OPT => 'for all columns size skewonly', 6 CASCADE => TRUE, 7 DEGREE => 7); 8END;
其中,DEGREE指定了並行度視主機的CPU個數而定,ESTIMATE_PERCENT指定了採樣比率,此處使用了AUTO目的是讓Oracle來決定採樣收集的比率,繪製直方圖時會根據採樣的數據分析結果來繪製,固然也能夠人爲指定採樣比率。如:ESTIMATE_PERCENT=>20指定採樣比率爲20%,CASCADE=>TRUE指定收集相關表的索引的統計信息,該參數默認爲FALSE,所以使用DBMS_STATS收集統計信息時默認是不收集表的索引的統計信息的。
關於直方圖的一些注意事項:
① 對於超過32個字符的字符型列,超出的那一部分沒法在直方圖中體現,這種先天性的缺陷會直接影響CBO對相關文本型字段的可選擇率及返回結果集的Cardinality的評估。
② 數字和日期在直方圖上被精確表示。
③ 若是目標列的數據是均勻分佈的(例如,主鍵列、惟一索引列),那麼就不須要對這些列收集直方圖統計信息。
④ 對於那些歷來沒有在WHERE條件中出現過的列,不管其數據分佈是否均勻,都無須對這些列收集直方圖統計信息。
⑤ 若是某個列從未在WHERE條件中出現過,那麼SYS.COL_USAGE$中就不會有這個列的使用記錄,那麼Oracle在以默認方式自動收集統計信息時就不會收集這個列的直方圖統計信息。
⑥ 若是目標列的DISTINCT值的數量和目標表的記錄數據量相同,即便該目標列在SYS.COL_USAGE$中有使用記錄,那麼Oracle在自動收集直方圖統計信息的時候也不會對該列收集直方圖統計信息。
⑦ Oracle是怎麼來判斷某列的數據分佈是不是傾斜的呢?Oracle採用了一種很簡單的方法來判斷某列是否傾斜,就是判斷目標列的DISTINCT值的數量是否和目標表的記錄數量相同,若是相同,那麼Oracle就認爲該列的數據分佈不是傾斜的,不然就是傾斜的。
⑧ 若是目標列的DISTINCT值的數量和目標表的數據量相同(即數據分佈不傾斜),即便該目標列在SYS.COL_USAGE$中有使用記錄,那麼Oracle在自動收集直方圖統計信息的時候也不會對該列收集直方圖統計信息。
⑨ 「在手工收集直方圖統計信息的時候,若是手工指定的Bucket的數量等於目標列的DISTINCT值的數量,且這個值是小於等於254的話,那麼Oracle此時收集的直方圖統計信息的類型應該是FREQUENCY」——這個結論成立的前提條件是該列的數據分佈是傾斜的。
本文選自《Oracle程序員面試筆試寶典》,做者:小麥苗
詳細內容能夠添加麥老師微信或QQ私聊。
About Me:小麥苗
● 本文做者:小麥苗,只專一於數據庫的技術,更注重技術的運用
● 做者博客地址:http://blog.itpub.net/26736162/abstract/1/
● 本系列題目來源於做者的學習筆記,部分整理自網絡,如有侵權或不當之處還請諒解
● 版權全部,歡迎分享本文,轉載請保留出處
● QQ:646634621 QQ羣:618766405
● 提供OCP、OCM和高可用部分最實用的技能培訓
● 題目解答如有不當之處,還望各位朋友批評指正,共同進步
長按下圖識別二維碼或微信掃描下圖二維碼來關注小麥苗的微信公衆號:xiaomaimiaolhr,學習最實用的數據庫技術。