統計資訊是如何提高SQLServer查詢效能的?統計直方圖用作在查詢執行計劃中查詢優化器的選擇依據。如果一個查詢謂詞包含統計資訊的列,那麼查詢優化器不需要預測該查詢中影響行數,因此,查詢優化器有足夠的資訊去建立執行計劃。SQLServer建立執行計劃有一下幾種不同的方式:
- 統計資訊會在每個新建立的索引中自動建立統計資訊。
- 如果資料庫中AUTO_CREATE_STATISTICS被設定為ON,SQLServer將會自動對查詢中用到的,且沒有索引的列自動建立統計資訊。
AUTO_CREATE_STATISTICS選項:
當把該選項設為ON時,查詢優化器會對在謂詞中使用的到列,如果這些列的統計資訊不可用,則會單獨對每列建立統計資訊。這些統計資訊對建立一個查詢計劃非常必要。它們建立於那些現有統計物件中不存在直方圖的列上,名字包括列名和物件ID的十六進位制格式:_WA_Sys_<column_name>_<XXXX>。這些統計資訊用於查詢優化器決定使用何種優化後的執行計劃。
可以通過以下語句啟用自動統計資訊建立功能:
ALTER DATABASE[你的庫名] SET AUTO_CREATE_STATISTICS ON |
Auto Update Statistics選項:
統計資訊會在查詢編譯或者執行快取執行計劃前被檢查。當在以下情況下,統計資訊會被認為過期:
1、 在一個空表中有資料的改動。
2、 當統計資訊建立時,表的行數只有500或以下,且後來統計物件中的引導列的更改次數大於500.
3、 當表的統計資訊收集時,超過了500行,且統計物件的引導列後來更改次數超過500+表總行數的20%時。
4、 在Tempdb中的表,少於6行且最少有6行被更改。
更多的資訊可以檢視MSDN
可以使用一下語句來開啟自動更新統計資訊:
ALTER DATABASE[你的庫名] SET AUTO_UPDATE_STATISTICS ON |
過時的統計資訊會引起大量的效能問題,所以建議開啟自動更新。它的預設設定是ON。沒有更新統計資訊常見的影響是選擇了次優的執行計劃,然後效能下降。有時候,過期的統計資訊可能比沒有統計資訊更加糟糕。
使用以下語句來開啟非同步更新統計資訊:
ALTER DATABASE[你的庫名] SET AUTO_UPDATE_STATISTICS_ASYNC ON |
如果開啟了這個選項,查詢優化器將先執行一次查詢,然後更新過期的統計資訊。當你把這個選項設為OFF時,查詢優化器將在編譯查詢之前更新過期統計資訊。這個選項在OLTP環境下很有用,但在資料倉儲中有負面影響。
如何關閉SQLServer自動更新統計資訊的選項?
在非常特殊的情況下,你不得不禁用這個有用的特性,可以使用以下方式關閉:
1、 使用sp_autostats來在表、索引或者統計物件上顯式並更改自動更新統計資訊選項。
2、 在表級別中,可以使用NORECOMPUTEoption of the UPDATE STATISTICS命令。
3、 你也可以在CREATESTATISTICS命令中使用NORECOMPUTE選項,但之後需要刪除並重建統計資訊。
4、 在CREATE INDEX命令中使用STATISTICS_NORECOMPUTE。
5、 在資料庫級別,可以使用以下命令來禁用:
ALTER DATABASE[你的庫名] SET AUTO_UPDATE_STATISTICS OFF |
當使用資料庫級別的禁用時,表、索引或者統計物件的設定將全部失效。
何時建立統計資訊?
其中一個答案是當使用資料庫引擎優化顧問(DTA)時建議建立。另外一個情況是當你檢視執行計劃是,出現丟失統計資訊的警告(missing statistics warnings),如下圖的黃色三角歎號:
可以使用SQLServer Profiler 去監控丟失列統計資訊的事件,你也可以考慮當你的查詢從子集或者查詢謂詞中包含關聯列的那些列上建立統計資訊。
建立統計資訊的語句如下:
--Create statistics on all rows CREATE STATISTICSstatistics_name ONYourDBName.YourSchema.YourTable(YourColumn1,YourColumn2) WITH FULLSCAN --Create statistics using a random 10 percent sampling rate CREATE STATISTICSstatistics_name ONYourDBName.YourSchema.YourTable(YourColumn1,YourColumn2) WITH SAMPLE 10PERCENT |
何時更新統計資訊?
如果你的查詢執行得很慢,那麼是時候更新統計資訊了。並且建議當你插入大量資料到升序或者降序的列時,更新統計資訊,因為在這種情況下,統計資訊直方圖將不包含新插入的值,同時,強烈建議在除索引維護(當你重建、整理碎片或者重組索引時,資料分佈不會改變)外的維護工作之後更新統計資訊。
如果資料庫的資料更改頻繁,建議最低限度每天更新一次統計資訊。一般來說,在資料倉儲中,可以降低更新統計資訊的頻率,當更新時,通常建議執行sp_updatestats儲存過程來實現。