[zt] Histograms - 直方圖

tolywang發表於2008-09-09

      什麼時候需要使用Histograms?如果表格內有20column,其中最常被使用在查詢的條件句內的只有一個column A,另外有個column B很少被拿來做查詢條件使用。現在你發現欄位A和欄位B的儲存資料非常的skewed,就是假設儲存的一百萬筆rows,有99%的值相等,只有1%的值是零散的,這就叫做歪斜的儲存值。

 

      瞭解了skewed後,回到問題就是兩個欄位AB儲存的值都是非常不平均,這時候optimizer很難準確的評估一個query statement所產生執行計劃的最佳選擇性。所以我們可以利用Histograms來幫助optimizer選擇最適當的選擇計劃。他的意義簡單的說就是假設有一袋米,裡面有成千上萬個壽司米,和混雜1%的在來米、中興米、糯米等,當我查詢為select * from米袋where品種=壽司米,應該採用full table scan或者使用建立在品種欄位上的索引?這個範例顯然使用FTS是比較有效率的,但為了幫助optimizer瞭解,我們拿了75個籃子,我們把所有的米平均且依照品種依序放在75個籃子內,你可以很輕易看出除了幾籃的在來米、中興米之外,絕大部分裝的都是壽司米,這就是建立histograms的目的。

     回到一開始的問題,欄位AB都是highly-skewed data,唯一差別是我們很少利用欄位B在做查詢條件句,那需要只對欄位A建立histograms或者兩者皆要,又或者表格內所有的欄位都應該需要建立,才能更加提升效能呢?

當該欄位資料並沒有發生skewed狀況時

當該欄位很少用來做查詢where條件時

我們不需要在該欄位建立histograms,就算建了也不會對performance有所提升。

DBMS_STATS.GATHER_TABLE_STATS (NULL,'EMP', method_opt =>'FOR COLUMNS sal SIZE 100');size指的是buckets數量,白話的就是建幾個籃子來裝,越多當然相對的平均,不過要看你資料特性來決定不是越大越好,可以嘗試的調整來找出最佳的值,預設值是75

      在正常的資料分佈而是沒有資料的某種分佈偏差的情況下,如果收集histograms統計資訊,在cursor_sharing這個引數設定為similar的時候容易出現cursor的子版本過多的問題。所以在使用histograms的時候需要注意這個問題。 

      之所以產生這樣的原因是這樣的:在使用收集histogram統計資料之後,如果使用使用繫結變數,histogram資料將不會被使用。在我們設定引數cursor_sharing有三種選擇:如果是force的時候,這時候,Oracle會將文的變數無論三七二十一就變成需要的繫結變數的形式,這樣我們採集的histogram資料將不會被使用。也就達不到我們所需要的最佳化效果了。如果設定為exact的時候,就會被不使用繫結變數,如果自己本身沒有繫結變數的時候,如果設定為similar的時候,每一次最佳化器會根據histogram統計資料解析SQL,以達到最優的結果。但是如果這個資料的分佈並不是有分佈不均得現象,就不要使用histogram統計資料,這或許是為什麼在Oracle的文件中說:

Do not use histograms unless they substantially improve performance.

的其中一個原因之一了。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-442655/,如需轉載,請註明出處,否則將追究法律責任。

相關文章