1. 程式人生 > >SQL調優技巧:統計信息(文末福利)

SQL調優技巧:統計信息(文末福利)

SQL 統計信息 優化器

點擊上方“異步社區”,選擇“置頂公眾號”

技術幹貨,第一時間送達


統計信息類似於戰爭中的偵察兵,如果情報工作沒有做好,打仗就會輸掉戰爭。同樣的道理,如果沒有正確地收集表的統計信息,或者沒有及時地更新表的統計信息,SQL的執行計劃就會跑偏,SQL也就會出現性能問題。收集統計信息是為了讓優化器選擇最佳執行計劃,以最少的代價(成本)查詢出表中的數據。

統計信息主要分為表的統計信息、列的統計信息、索引的統計信息、系統的統計信息、數據字典的統計信息以及動態性能視圖基表的統計信息。

關於系統的統計信息、數據字典的統計信息以及動態性能視圖基表的統計信息本文不做討論,本文重點討論表的統計信息、列的統計信息以及索引的統計信息。

表的統計信息主要包含表的總行數(num_rows)、表的塊數(blocks)以及行平均長度(avg_row_len),我們可以通過查詢數據字典DBA_TABLES獲取表的統計信息。

現在我們創建一個測試表T_STATS。

技術分享圖片

我們查看表T_STATS常用的表的統計信息。

技術分享圖片


因為T_STATS是新創建的表,沒有收集過統計信息,所以從DBA_TABLES查詢數據是空的。

現在我們來收集表T_STATS的統計信息。

技術分享圖片

我們再次查看表的統計信息。

技術分享圖片


從查詢中我們可以看到,表T_STATS一共有72?674行數據,1?061個數據塊,平均行長度為97字節。

列的統計信息主要包含列的基數、列中的空值數量以及列的數據分布情況(直方圖)。我們可以通過數據字典DBA_TAB_COL_STATISTICS查看列的統計信息。

現在我們查看表T_STATS常用的列統計信息。

技術分享圖片


上面查詢中,第一個列表示列名字,第二個列表示列的基數,第三個列表示列中NULL值的數量,第四個列表示直方圖的桶數,最後一個列表示直方圖類型。

在工作中,我們經常使用下面腳本查看表和列的統計信息。

技術分享圖片


索引的統計信息主要包含索引blevel(索引高度-1)、葉子塊的個數(leaf_blocks)以及集群因子(clustering_factor)。我們可以通過數據字典DBA_INDEXES查看索引的統計信息。

我們在OBJECT_ID列上創建一個索引。

技術分享圖片

創建索引的時候會自動收集索引的統計信息,運行下面腳本查看索引的統計信息。

技術分享圖片

在以後章節中,我們會詳細介紹表的統計信息、列的統計信息以及索引的統計信息是如何被應用於成本計算的。

統計信息重要參數設置

我們通常使用下面腳本收集表和索引的統計信息。

技術分享圖片

ownname表示表的擁有者,不區分大小寫。

tabname表示表名字,不區分大小寫。

granularity表示收集統計信息的粒度,該選項只對分區表生效,默認為AUTO,表示讓Oracle根據表的分區類型自己判斷如何收集分區表的統計信息。對於該選項,我們一般采用AUTO方式,也就是數據庫默認方式,因此,在後面的腳本中,省略該選項。

estimate_percent 表示采樣率,範圍是0.000 001~100。

我們一般對小於1GB的表進行100%采樣,因為表很小,即使100%采樣速度也比較快。有時候小表有可能數據分布不均衡,如果沒有100%采樣,可能會導致統計信息不準。因此我們建議對小表100%采樣。

我們一般對表大小在1GB~5GB的表采樣50%,對大於5GB的表采樣30%。如果表特別大,有幾十甚至上百GB,我們建議應該先對表進行分區,然後分別對每個分區收集統計信息。

一般情況下,為了確保統計信息比較準確,我們建議采樣率不要低於30%。

我們可以使用下面腳本查看表的采樣率。

技術分享圖片

從上面查詢我們可以看到,對表T_STATS是100%采樣的。現在我們將采樣率設置為30%。

技術分享圖片


從上面查詢我們可以看到采樣率為30%,表的總行數被估算為73?067,而實際上表的總行數為72?674。設置采樣率30%的時候,一共分析了21?920條數據,表的總行數等於round(21?920*100/30),也就是73?067。

除非一個表是小表,否則沒有必要對一個表100%采樣。因為表一直都會進行DML操作,表中的數據始終是變化的。

method_opt 用於控制收集直方圖策略。

method_opt => 'for all columns size 1'

表示所有列都不收集直方圖,如下所示。

技術分享圖片

我們查看直方圖信息。

技術分享圖片


從上面查詢我們看到,所有列都沒有收集直方圖。

method_opt => 'for all columns size skewonly'

表示對表中所有列收集自動判斷是否收集直方圖,如下所示。

技術分享圖片

我們查看直方圖信息,如下所示。

技術分享圖片


從上面查詢我們可以看到,除了OBJECT_ID列和EDITION_NAME列,其余所有列都收集了直方圖。因為EDITION_NAME列全是NULL,所以沒必要收集直方圖。OBJECT_ID列選擇性為100%,沒必要收集直方圖。

在實際工作中千萬不要使用

method_opt => 'for all columns size skewonly'

收集直方圖信息,因為並不是表中所有的列都會出現在where條件中,對沒有出現在where條件中的列收集直方圖沒有意義。

method_opt => 'for all columns size auto'

表示對出現在where條件中的列自動判斷是否收集直方圖。

現在我們刪除表中所有列的直方圖。

技術分享圖片

我們執行下面SQL,以便將owner列放入where條件中。

技術分享圖片

接下來我們刷新數據庫監控信息。

技術分享圖片

我們使用method_opt => 'for all columns size auto'方式對表收集統計信息。

技術分享圖片

然後我們查看直方圖信息。

技術分享圖片


從上面查詢我們可以看到,Oracle自動地對owner列收集了直方圖。

思考,如果將選擇性比較高的列放入where條件中,會不會自動收集直方圖?現在我們將OBJECT_NAME列放入where條件中。

技術分享圖片

然後我們刷新數據庫監控信息。

技術分享圖片

我們收集統計信息。

技術分享圖片

我們查看OBJECT_NAME列是否收集了直方圖。

技術分享圖片

從上面查詢我們可以看到,OBJECT_NAME列沒有收集直方圖。由此可見,使用AUTO方式收集直方圖很智能。mothod_opt默認的參數就是 for all columns size auto。method_opt => 'for all columns size repeat'表示當前有哪些列收集了直方圖,現在就對哪些列收集直方圖。


本文摘自《SQL優化核心思想》

技術分享圖片

《SQL優化核心思想》

羅炳森 黃超 鐘僥 著

點擊封面購買紙書

結構化查詢語言(Structured Query Language,SQL)是一種功能強大的數據庫語言。它基於關系代數運算,功能豐富、語言簡潔、使用方便靈活,已成為關系數據庫的標準語言。 本書旨在引導讀者掌握SQL優化技能,以更好地提升數據庫性能。本書基於Oracle進行編寫,內容講解由淺入深,適合各個層次的讀者學習。

本書面向一線工程師、運維工程師、數據庫管理員以及系統設計與開發人員,無論是初學者還是有一定基礎的讀者,都將從中獲益。

小福利

關註【異步社區】服務號,轉發本文至朋友圈或 50 人以上微信群,截圖發送至異步社區服務號後臺,並在文章底下留言你學習SQL語言經驗,或者試讀本書感受,我們將選出3名讀者贈送《SQL優化核心思想》1本,趕快積極參與吧!
活動截止時間:2018年 5月10 日


技術分享圖片

“異步社區”後臺回復“關註”,即可免費獲得2000門在線視頻課程;推薦朋友關註根據提示獲取贈書鏈接,免費得異步圖書一本。趕緊來參加哦!

掃一掃上方二維碼,回復“關註”參與活動!

閱讀原文,購買《SQL優化核心思想》

閱讀原文


SQL調優技巧:統計信息(文末福利)