前言:統計信息作為sql server優化器生成執行計划的重要參考,需要數據庫開發人員,數據庫管理員對其有一定的理解,從而合理高效的應用,管理.
第一部分 概念
統計信息(statistics):描述某個(些)欄位,索引的數據分布情況.優化器用其評估生成高效執行計划.
密度(density):一個比率值,顯示在一個(組)列中有多少唯一值.(實際應用中值越小越好)
Density = 1 / Number of distinct values for column(s)
直方圖(histogram):將數據分割成不同的段(steps),用於描述,記錄每段數據分布的具體情況(抽樣創建).最多分為200 steps
DBCC show_statistics(object_name,Column_name)
Header(信息頭)包含統計信息一系列元數據
Density(密度)包含列(列組)的密度信息及平均列(組)長度
Histogram(直方圖)包含直方圖描述信息.
Histogram(直方圖)
RANGE_HI_KEY:直方圖列(多列情況為首列記錄)段的上限值.列值就是鍵值
RANGE_ROWS:其相應列值位於此段(不包含上限)的行得數量(估計值)
EQ_ROWS:等於其列值上限值的行數
DISTINCT_RANGE_ROWS: RANGE_ROWS中的非重復值數量
AVG_RANGE_ROWS:直方圖段內值得平均行數(不包括上限)
DISTINCT_RANGE_ROWS > 0則為RANGE_ROWS / DISTINCT_RANGE_ROWS
第二部分 原理,應用
統計信息更新
統計信息可以人工維護更新或是由優化器在確認執行計划有效時依據之一:重編譯閾值(recompilation threshold/RT)來決定統計信息是否過期而執行更新.
觸發條件
當創建的表為空表時,添加一條數據則更新
當表數據小於500行時,記錄更新標識(Modification Counters)大於500更新
當表數據大於500行時,記錄更新標識大於500且20%行數變化(rowcnt)
注:臨時表表很小(0行或者小於6行).6次變更觸發更新.
表變量無統計信息
關於記錄更新標識(Modification Counters)
Rowmodctr sql2000及之前使用.記錄在sys.sysindexes中.
注:此參數雖然高版本依賴其使用,但微軟目前仍維護此參數變化可作為參考
colmodctr sql2005及以后使用記錄在sys.sysrscols. rcmodified中(需DAC訪問)
此外DMV sys.system_internals_partition_columns的modified_count同樣記錄
Colmodctr(無需DAC)但不提供向上兼容.目前sql2012依然支持!
Colmodctr記錄規則:
Insert 每添加一行所有列 Colmodctr+1=Colmodctr
Delete 每刪除一行所有列Colmodctr+1=Colmodctr
Update 每修改一行 更新目標列Colmodctr+1=Colmodctr(sql2008+)
Sql2005更新目標列
當修改列為NOKEY columns時Colmodctr+1=Colmodctr
當修改列為KEY columns時Colmodctr+2=Colmodctr
Bulk Insert 與N Rows Insert類似
Truncate table 與N Rows delete類似
注: Modification Counters非事務(如當插入1000條數據,然后rollback. Colmodctr會加1000)
過濾統計信息(filtered statistics)觸發更新為整體數據區間而非過濾區間.一旦創建需人工維護
優化器應用統計信息.
優化器如何應用統計信息是一個比較復雜的方式.Sql Server在各版本之間應用方式甚至不盡相同.這里只做簡單介紹.
優化器使用Statistics”偏好” 優先考慮最新的,Full Scan的統計信息
簡單介紹下等式單謂詞預估.
dbcc show_statistics('votes','IX_MultiColumn1')
select * from votes where topic_id=40
當謂詞命中邊界值時預估行數為EQ_ROWS
select * from votes where topic_id=10000
當謂詞值在某個區間內,非命中邊界值,預估值為AVG_Range_ROWS.即9042至16234間的所有謂詞鍵值預估均為2.482208
declare @topic_id int
set @topic_id =1000
select * from votes where topic_id=@topic_id
當謂詞為變量形式時,優化器不知道參數值.將采用 密度*行數的形式預估.
即topic_id=@topic_id 為0.000004936151*1943794=9.59486
第三部分 維護
查看統計信息
sp_autostats 'votesbak'---查看統計信息更新信息
sp_helpstats 'votesbak','all' ---查看統計信息對應列/鍵值
dbcc show_statistics('votes','IX_MultiColumn1')—查看特定統計信息的詳細內容
統計信息相關設置
AUTO_CREATE_STATISTICS ----自動創建統計信息
AUTO_UPDATE_STATISTICS ---自動更新統計信息
AUTO_UPDATE_STATISTICS_ASYNC --自動異步更新統計信息(優化器會用舊的統計信息,而不重編譯,立即執行.)
例子:
ALTER DATABASE [BitautoReview2] SET AUTO_UPDATE_STATISTICS_ASYNC ON
Trace Flag 2371 彈性根據條件更新統計信息
統計信息操作
Create Statistics --創建統計信息
Update Statistics --更新統計信息
Drop Statistics --刪除統計信息
維護統計信息時可選擇樣本量來進行創建,更新
update statistics [votes](IX_MultiColumn1) with fullscan--手動更新指定索引的統計信息(一般針對特定統計信息問題時使用全掃描.更新時間較長可能影響性能)
UPDATE STATISTICS Votes WITH SAMPLE 10 Percent;-----手動更新全表統計信息,樣本采樣10%(一般針對更新整個對象時使用,樣本量與精確程度依環境而定)
UPDATE STATISTICS votes WITH ROWCOUNT =1000000,PAGECOUNT=100000---指定更新行數/頁數(一般用於模擬當表數據量變得巨大時,優化器將采用何種執行計划)
統計信息最佳實踐
AUTO_CREATE_STATISTICS , AUTO_UPDATE_STATISTICS一般無特殊應用自動打開.
AUTO_UPDATE_STATISTICS_ASYNC當觸發更新的表巨大,統計信息更新會明顯影響當前性能,且舊的統計信息對原有更新無明顯影響時應設置為ON
Trace flag 2371 根據相應環境設置
由表變量造成的因無統計信息而使執行計划糟糕的情況用臨時表代替
只讀庫(Readonly)配置前應創建相應統計信息
盡量避免變量,使用PROC傳參形式,當使用動態SQL時用exec sp_executesql形式
過濾統計信息應人為維護
表達式(CTE)再參與Join的操作后,可能因執行邏輯無法獲取准確統計信息,當出現此問題時用臨時表或重寫等方式代替
當數據傾斜很大,造成參數嗅探等問題時,應創建過濾統計信息(過濾索引),或是用query Hint,重寫邏輯處理等方式處理.