1)在oracle中使用直方圖來表示數據的分布質量。它會根據壹列中不同值的個數和出現的頻率來繪制數據的分布,從而指導優化器根據數據的分布做出正。
確切的選擇(是使用索引還是全表掃描)。
2)如果where子句中的filter謂詞的列上有壹個合理正確的直方圖,對於優化器做出正確的選擇,使sql語句的執行成本最低,提高性能會起到很大的作用。在獲得準確的直方圖信息後
之後,基於成本的優化器可以決定使用返回幾行的索引,而不是基於約束返回許多行的索引。
3)直方圖的使用不受索引的限制,直方圖可以建立在表的任何列上。構造直方圖的主要原因是為了幫助優化器在表中的數據嚴重傾斜時做出更好的選擇。例如,壹個或兩個值(狀態=0
而status=1,其中=0有100條數據,=1有1000000條數據,只有這兩個值)構成了表中的大部分數據(數據偏斜),相關查詢可能無助於減少滿足查詢(比如查詢)所需的I/O數量
狀態=1).創建直方圖可以讓基於成本的優化器知道什麽時候最適合使用索引,或者什麽時候根據where子句中的值返回表中80%的記錄。
4)通常建議在以下情況下創建和使用直方圖:
1)當where子句引用的列值分布有明顯偏差的列時,當偏差如此明顯以至於where子句中的值會使優化器選擇不同的執行計劃時。在這種情況下,應使用直方圖來幫助優化。
設備來更正執行路徑。(註意:如果查詢沒有引用該列,那麽創建直方圖就沒有意義。這種錯誤非常常見,許多DBA會在偏差列上創建壹個直方圖,即使沒有查詢引用該列)
2)列值導致判斷錯誤時:這種情況通常發生在多個表連接的情況下。例如,假設有壹個五項表連接,其結果集只有10行記錄。Oracle將以第壹個連接的結果集(集基數)結束。
以小的方式連接表是可能的。通過減少中間結果集中的負載,查詢將運行得更快。為了最小化中間結果集,優化器會在sql執行的分析階段嘗試評估每個結果集的集基數。
偏離列上的直方圖將極大地幫助優化器做出正確的決策。如果優化器對中間結果集的大小做出了錯誤的判斷,它可能會選擇壹個未優化的表連接方法,因此它會在列中添加壹個直線。
方形圖通常為優化器提供使用最佳連接方法所需的信息。
5)直方圖的分類:可分為等頻直方圖和等高直方圖。
等頻直方圖:對於很少有不同值的數據集,數據分布是均勻的。
等高線直方圖:用於具有許多不同值的數據集。數據分布不均勻。因為列中有大量數據,此時數據密集,不利於分析評估。此時,直方圖需要默認平衡。如果傾斜柱上的柱是唯壹的,
如果壹個值超過254,oracle將為此列創建壹個輪廓直方圖,否則,將建立壹個等頻率直方圖。
直方圖信息的準確性由兩個數值決定,壹個是桶的數量,另壹個是num_distinct的數量。壹般來說,桶越多,關於列數據分布的信息越準確,但是統計直方圖所花費的時間
此外,oracle中的最大存儲桶數是254,默認是75。sql server中的默認值為200。通常當bucet
當BUCTET > Table NUM_DISTINCT值時,就得到頻率直方圖。因為滿足BUCTET = table的NUM_DISTINCT值的概率很低,所以Oracle中生成的大多數直方圖都是
高度平衡直方圖。在Oracle 10GR2之前,如果使用dbms_stats包創建直方圖,那麽如果指定要創建的直方圖的桶數等於表的NUM_DISTINCT值,那麽差不多。
無法創建頻率直方圖,此時,為了得到頻率直方圖,我們只能使用analyze命令的" NUM _ DISTINCT value of for all columns size table ",這在某種程度上是壹種倒退,但這
該問題在Oracle 10GR2之後得到了修復。但是,如果列中有180-200個不同的值,仍然無法創建頻率直方圖。這時候就需要手動創建直方圖並寫入數據字典來完成頻率。
直方圖的創建。對於差異值很少且數據分布非常不均勻的數據集,創建頻率直方圖會更合適,因為不存在低頻出現的記錄會被存儲在高頻桶中的情況。
,並且當桶的數量沒有被適當分配時,高度平衡直方圖可能出現。因此,在創建直方圖之前,需要確定使用哪個直方圖,並合理地估計桶。
號碼。
6)如何創建直方圖:
可以使用早期的analyze命令和最新的dbms_stats工具包來創建直方圖。Oracle推薦使用後者來創建直方圖,直方圖的創建不受任何條件限制,可以在任何想要的表上創建。
在直方圖的列上創建直方圖。這裏主要介紹如何通過dbms_stats包創建直方圖。
Oracle通過指定dbms_stats的method_opt參數來創建直方圖。method_opt子句中有三個相關選項,即skewonly、repeat和auto。
“skewonly”選項對時間非常敏感,因為它檢查每個索引中每個列的值的分布。如果dbms_stats找到壹個列分布不均勻的索引,它將為該索引創建壹個直方圖,以幫助基於成本的SQL。
優化器決定是使用索引還是全表掃描訪問。例子如下:
開始
dbms_stats。收集_表格_統計信息(
ownname = & gt'',
tabname = & gt'',
estimate _ percent = & gtdbms_stats.auto_sample_size,
method _ opt = & gt對於所有列大小skewonly ',
cascade = & gt沒錯,
degree = & gt7);
結束;
Degree指定並行度取決於主機的CPU數量,estimate_percent指定采樣比率。這裏用auto讓oracle決定采樣采集比例,直方圖會根據采樣數據的分析結果繪制。
要畫,當然也可以人為指定采樣率。例如,estimate_percent= >20指定采樣率為20%,cascade = & gtTrue指定收集相關表的索引統計信息。這個參數默認為false,所以使用dbms_stats。
默認情況下,收集統計信息不會收集表的索引信息。
監控表(alter table xxx monitoring)使用auto選項,該選項根據數據分布和應用程序訪問列的方式(如通過監視確定的列負載)創建直方圖。例子如下:
開始
dbms_stats.gather_ table _stats(
ownname = & gt'',
tabname = & gt'',
estimate _ percent = & gtdbms_stats.auto_sample_size,
method _ opt = & gt對於所有列大小自動',
cascade = & gt沒錯,
degree = & gt七
);
結束;
重新分析統計數據時,使用repeat選項將消耗更少的資源。當使用repeat選項時,將僅對現有直方圖重新分析索引,而不會生成新的直方圖。例子如下:
dbms_stats.gather_ table _stats(
ownname = & gt'',
tabname = & gt'',
estimate _ percent = & gtdbms_stats.auto_sample_size,
method _ opt = & gt對於所有列大小重復',
cascade = & gt沒錯,
degree = & gt七
);
結束;
VII)創建直方圖的註意事項:
如果要為某壹列創建直方圖,示例如下:
dbms_stats.gather_ table _stats(
ownname = & gt'',
tabname = & gt'',
estimate _ percent = & gtdbms_stats.auto_sample_size,
method _ opt = & gt對於大小為10的列名',
cascade = & gt沒錯,
degree = & gt七
);
結束;
其中,大小10指定了直方圖所需的桶數。所謂桶,可以理解為存儲數據的容器,它會根據數據的分布,盡可能地將數據平均到每個桶,比如壹個表有6000個條目。
記錄,那麽每個桶中平均會有600條記錄,但這只是平均值,每個桶中的記錄數不會相等。它會把高頻記錄集中在壹些桶裏,低頻記錄會存儲在幾個桶裏,所以如果存儲的話,
適當增加桶的數量會減少用於高頻記錄的桶的數量,統計結果會更加準確(可以避免被迫將低頻記錄存儲在高頻桶中,影響優化器生成準確的執行計劃)。所以我們最終不得不
獲得的直方圖信息的精度由兩個數值決定,壹個是BUCTET的數量,另壹個是NUM_DISTINCT的數量。因此,在創建直方圖時,我們必須首先正確估計桶的數量。默認情況下,甲骨文是直的
正方形圖將產生75個桶。您可以指定1~254之間的SIZE值。
8)刪除直方圖信息:
要在oracle中刪除直方圖信息,需要將時段數據設置為1,如下所示:
分析表表計算id大小為1的列的統計信息;
exec DBMS _ stats . gather _ table _ stats(' user ',' table ',cascade = >;false,method _ opt = & gt對於列,列大小為1’);
但是,再次收集該表的統計信息是不合理的。11g有以下方法直接刪除直方圖信息。
dbms_stats.delete_column_stats
ownname = & gt'',
tabname = & gt'',
colname = & gt'',
col _ stat _ type = & gt直方圖’)
相關測試實驗請參考:/s/blog _ 63972 ba 20100 x3mh . html。
9)直方圖和綁定變量
主測試直方圖不適合使用綁定變量的sql語句:/Scott _ Guo/blog/static/102608320122551225491/
x)檢查表格是否有直方圖信息。
User_Tab_Histograms(公共表)和User_Part_Histograms(表分區)中有相關表的記錄嗎?
查詢索引的選擇率:索引選擇率= distinct _ keys/num _ rows * 100%。如果該值很小,則數據分布不均勻。
選擇壹個所有者,
a .索引名稱,
a .索引類型,
分區的,
B.num _ rows,-表示表中有多少條記錄。
B.distinct _ keys,-表示索引的列中有多少不同的值。
b . num _ rows/b . distinct _ keys avg _ row _ per _ key,
b.distinct_keys / b.num_rows選擇性,
b .最後分析的,
b .陳舊統計數據
來自數據庫索引a,數據庫索引統計b
其中a .所有者= b .所有者
並且a .索引名稱= b .索引名稱
-和a . table _ name = ' Q _ PARTITION _ RANGE '
並且a . INDEX _ name = ' INDEX _ LR _ qossstaffid _ RANGE '
查詢該列上是否有直方圖:
select owner,table_name,column_name,num_distinct,histogram,num _ buckets from DBA _ tab _ col _ statistics
其中,表名= ' Q _分區_範圍'和列名='LR_STAFFID '
Num_buckets為1表示該列沒有直方圖。
有時候,使用dbms_stats收集統計信息後,它不會取索引或者我們期望取的索引。這時候用analyze收集統計信息,確實可以取指數;但是,在使用analyze收集統計信息後,索引的相應列上可能沒有直線。
這時可以使用dbms_stats來收集平方圖信息,然後查詢該列是否有直方圖信息。如果有要再次執行的語句,看它是否被索引。如果沒有索引,可以通過dbms_stats刪除已更改列的直方圖信息:
EXEC DBMS_STATS。GATHER _ TABLE _ STATS(own name = & gt;',TABNAME = & gt',ESTIMATE _ PERCENT = & gt100,DEGREE= >16,method_opt= >對於大小為1 LR_STAFFID '的列,CASCADE = & gt真);
然後驗證該列是否有直方圖信息,並執行sql來查看它是否被索引。