天天看點

第13/24周 統計資訊

歡迎來到性能調優教育訓練的第4個月。這個月全是關于SQL Server裡的統計資訊,還有它們如何幫助查詢優化器生成足夠好的執行計劃。統計資訊主要是被查詢優化器用來估計查詢傳回的行數。它隻是個估計,沒别的。

統計資訊概述

SQL Server使用在統計資訊對象裡稱作直方圖(Histogram)的東西,它描述了對于所給列最大200步長(Steps)的資料分布情況。最大的局限性之一,對于SQL Server裡的統計資訊是200步長的局限性(使用過濾統計資訊可以超過這個步長,這在SQL Server 2008裡就引入了)。

另外的局限性是統計資訊的自動更新(Auto Update)機制:對于大于500行的表,如果500+20%的列值發生改變,統計資訊才會更新。這就意味着,一旦表增長,你的統計資訊的自動更新頻率将越少(每次觸發自動更新需要更多的記錄修改)。

假設你有100000條記錄的表,這個情況下,如果修改了20500(20%+500)的資料,統計資訊才會自動更新。如果你有1000000條記錄的表,你需要修改200500(20%+500)的資料,統計資訊才會自動更新。這裡用到的算法是指數的,不是線性的。在SQL Server裡有2371的跟蹤标志(trace flag)也會影響這個行為。

當你的執行計劃裡保航書簽查找時,這個行為就會是巨大的問題。正如你知道的,基于目前的統計資訊,如果查詢的估計行數是非常少的,查詢優化器才會選擇書簽查找運算符。如果你的統計資訊過期,你的執行計劃還是有效的話,SQL Server就會盲目重用緩存計劃,你的頁讀取就會暴漲。我們來看看這個問題的具體例子。

失真的統計資訊(Stale Statistics)

下面的腳本會建立有1500條記錄的表,在column2列有平均的資料分布。另外我們在column2列上定義非聚集索引。

1 CREATE TABLE Table1
 2 (
 3    Column1 INT IDENTITY,
 4    Column2 INT
 5 )
 6 GO
 7 
 8 -- Insert 1500 records into Table1
 9 SELECT TOP 1500 IDENTITY(INT, 1, 1) AS n INTO #Nums
10 FROM
11 master.dbo.syscolumns sc1
12 
13 INSERT INTO Table1 (Column2)
14 SELECT n FROM #nums
15 
16 DROP TABLE #nums
17 GO 
18 
19 CREATE NONCLUSTERED INDEX idx_Table1_Colum2 ON Table1(Column2)
20 GO      

當你對表進行簡單的SELECT * 查詢時,你會得到帶有書簽查找運算符的執行計劃:

1 SELECT * FROM dbo.Table1 WHERE Column2='9'      
第13/24周 統計資訊
第13/24周 統計資訊

從索引查找(Non Clustered)運算符可以看到,SQL Server估計行數是1(估計行數(Estimated Number of Rows)屬性),實際上SQL Server也處理1條記錄(實際行數(Actual Number of Rows)屬性)。這就是說,我們這裡用到的統計資訊是準确的,查詢本身産生3個邏輯讀。

我們現在的表有1500條記錄,是以當20% + 500條記錄發生改變時,SQL Server會自動更新非聚集索引的統計資訊。算一下,我們需要修改800條資料(1500 * 20% + 500)。

接下來我們對表做如下處理:我們對SQL Server做一點動作,隻插入799條新記錄。但799條記錄的第2列值都是2。這就是說我們完全改變第2列的平均資料分布。統計資訊會認為隻有1條第2列值為2的記錄傳回,但實際上卻有800條記錄傳回(1條已存在的,799條新插入的):

1 SELECT TOP 799 IDENTITY(INT, 1, 1) AS n INTO #Nums
2 FROM
3 master.dbo.syscolumns sc1
4 
5 INSERT INTO Table1 (Column2)
6 SELECT 2 FROM #nums
7 
8 DROP TABLE #nums
9 GO      

現在我們來執行下列查詢語句,找第2列值為2的記錄,并打開執行計劃顯示和IO統計。 

1 SET STATISTICS IO ON
2 SELECT * FROM dbo.Table1 WHERE Column2 ='2'      

 SQL Server重用了有書簽查找的執行計劃。這就是說執行計劃裡的書簽查找執行了1500次——一次性對所有記錄!這會耗費大量的邏輯讀——SQL Server這裡報告了806個頁讀取。

第13/24周 統計資訊
第13/24周 統計資訊

從圖中可以看到,實際行數(Actual Number of Rows)現在已經遠遠超過了估計行數(Estimated Number of Rows)。

SQL Server裡失真的統計資訊就會帶來這樣的問題。

小結

今天的性能調優教育訓練我給你簡單介紹了SQL Server裡的統計資訊。如你所見,失真的統計資訊,對于緩存的,重用的執行計劃會帶來嚴重的性能問題。

我希望現在你已經能很好的了解SQL Server裡的統計資訊,當它們過期是,會給你的執行計劃帶來副作用。下周我會進一步讨論統計資訊,還有在SQL Server内部它們是怎樣的。請繼續關注。

圍觀PPT:

0817_13統計資訊.rar

注:此文章為

WoodyTu

學習MS SQL技術,收集整理相關文檔撰寫,歡迎轉載,請在文章頁面明顯位置給出此文連結!

若您覺得這篇文章還不錯請點選下右下角的推薦,有了您的支援才能激發作者更大的寫作熱情,非常感謝!

繼續閱讀