1. 程式人生 > >SQL SERVER的統計信息

SQL SERVER的統計信息

credit exp 精確 uid 序列值 microsoft 字節數 sum 資料

技術分享

可以看到,統計信息分為三部分內容,頭信息,數據字段選擇性及直方圖。

2.1 頭信息

列名 說明
Name 統計信息的名稱。
Updated 上次更新統計信息的日期何時間
Rows 預估表中的行數,不一定是精確的
Rows Sampled 統計信息的抽樣行數,如果小於Rows,則說明直方圖和密度結果是更加抽樣行估計的
Steps 直方圖中的梯級數。
Number of steps in the histogram.
每個梯級都跨越一個列值範圍,後跟上限列值。 直方圖梯級是根據統計信息中的第一個鍵列定義的。 最大梯級數為 200。
Density 計算公式為 1/統計信息對象第一個鍵列中的所有值(不包括直方圖邊界值)的非重復值。 查詢優化器不使用此 Density 值,顯示此值的目的是為了與 SQL Server 2008 之前的版本實現向後兼容。
Average key length 統計信息對象中所有鍵列的每個值的平均字節數。
String Index Yes 指示統計信息對象包含字符串摘要統計信息,以改進對使用 LIKE 運算符的查詢謂詞的基數估計;例如 WHERE ProductName LIKE ‘%Bike‘。
Yes indicates the statistics object contains string summary statistics to improve the cardinality estimates for query predicates that use the LIKE operator; for example, WHERE ProductName LIKE ‘%Bike‘.
字符串摘要統計信息與直方圖分開存儲,並當它是類型的統計信息對象第一個鍵列上創建char, varchar, nchar, nvarchar, varchar (max), nvarchar (max),文本,或ntext。
Filter Expression 包含在統計信息對象中的表行子集的謂詞。 NULL = 未篩選的統計信息。 有關篩選的謂詞的詳細信息,請參閱Create Filtered Indexes。 有關篩選的統計信息的詳細信息,請參閱統計信息。
Unfiltered Rows 應用篩選表達式前表中的總行數。 如果篩選表達式為 NULL,則 Unfiltered Rows 等於 Rows。

2.2 數據字段選擇性

列名 Description
Density 密度為 1/非重復值。 結果顯示統計信息對象中各列的每個前綴的密度,每個密度顯示一行。 非重復值是每個行前綴和列前綴的列值的非重復列表。 例如,如果統計信息對象包含鍵列 (A, B, C),結果將報告以下每個列前綴中非重復值列表的密度:(A)、(A,B) 以及 (A, B, C)。 使用前綴 (A, B, C),以下每個列表都是一個非重復值列表:(3, 5, 6)、(4, 4, 6)、(4, 5, 6) 和 (4, 5, 7)。 使用前綴 (A, B),相同列值則具有以下非重復值列表:(3, 5)、(4, 4) 和 (4, 5)
Average Length 存儲列前綴的列值列表的平均長度(以字節為單位)。 例如,如果列表 (3, 5, 6) 中的每個值都需要 4 個字節,則長度為 12 個字節。
columns 為其顯示 All density 和 Average length 的前綴中的列的名稱。

2.3 直方圖

列名Description
RANGE_HI_KEY 直方圖梯級的上限列值。 列值也稱為鍵值。
RANGE_ROWS 其列值位於直方圖梯級內(不包括上限)的行的估算數目。
EQ_ROWS 其列值等於直方圖梯級的上限的行的估算數目。
DISTINCT_RANGE_ROWS 非重復列值位於直方圖梯級內(不包括上限)的行的估算數目。
AVG_RANGE_ROWS 重復列值位於直 方圖梯級內(不包括上限)的平均行數(如果 DISTINCT_RANGE_ROWS > 0,則為 RANGE_ROWS / DISTINCT_RANGE_ROWS)。
直方圖,用於計算數據中每個非重復值出現的頻率。使用統計信息對象的第一個鍵列中的列值來計算直方圖,可以通過抽樣行或者全表掃描的形式。如果是抽樣創建,那麽,這裏邊的 存儲總行數何非重復值總數則為估計值。 創建直方圖的時候,查詢優化器對列值進行排序,同時計算每個非重復列值匹配的個數,然後將這列非重復列值 分為 1-200個連續的直方圖梯級中,每個梯級包含一個列值範圍,該範圍介於兩個邊界值之間的所有可能列值,不包含邊界值本身,最小的排序列值是第一個直方圖梯級的上限值。 回到頂部(go to top)

3 影響統計信息的選項

每個表格或者索引視圖 何時創建統計信息、基於哪些列創建統計信息及何時更新統計信息,需要根據 AUTO_CREATE_STATISTICS 、 AUTO_UPDATE_STATISTICS、 AUTO_UPDATE_STATISTICS_ASYNC 的設定值 來確定,這三個屬於 數據庫級別的選項,可以通過系統視圖查看,也可以通過 圖形界面選擇數據庫的“屬性”,查看“選項”。

技術分享
1 --查看數據庫統計信息選項設定值
2 SELECT
3       name dbname,
4       is_auto_create_stats_on,
5          is_auto_update_stats_on,
6          is_auto_update_stats_async_on
7 FROM sys.databases
技術分享

3.1 AUTO_CREATE_STATISTICS

默認為ON。自動創建統計信息選項,僅應用於 表格單列統計信息!!! 查詢優化器根據查詢謂詞的使用情況,在表格上單獨給某一列創建統計信息(這些單列暫時未創建直方圖),協助查詢計劃的基數估計。 該選項不決定是否為索引創建統計信息,也不生產篩選統計信息。 通過該選項創建的統計信息,名稱以 _WA 開頭。可以通過sys.stats視圖查看。 技術分享
1 SELECT OBJECT_NAME(s.object_id) AS object_name,
2     COL_NAME(sc.object_id, sc.column_id) AS column_name,
3     s.name AS statistics_name
4 FROM sys.stats AS s JOIN sys.stats_columns AS sc
5     ON s.stats_id = sc.stats_id AND s.object_id = sc.object_id
6 WHERE s.name like ‘_WA%‘
7 ORDER BY s.name;
技術分享

3.2 AUTO_UPDATE_STATISTICS

默認為ON。自動更新統計信息選項,查詢優化器自動確定統計信息何時過期何時需要更新。 通常情況,從上次自動更新至今,如果期間積累了較大數量的數據變更,包括插入、刪除及修改,或表結構變更等,均會造成統計信息過期。 該選項適用於為索引創建統計信息對象、查詢謂詞中的單列以及使用 create statistics 語句創建的統計信息。

3.3 AUTO_UPDATE_STATISTICS_ASYNC

默認為OFF。異步自動更新統計信息選項,確定查詢優化器是使用 同步統計信息更新還是異步統計信息更新。OFF則代表使用同步自動更新統計信息,這樣,查詢計劃始終使用最新的統計信息進行編譯執行,如果遇到統計信息過期,則會在查詢編譯前等待更新統計信息,若是異步自動更新統計信息,則在遇到統計信息過期時,直接使用現有統計信息編譯然後執行,即使可能由於統計信息過期造成編譯不佳,執行計劃非最優,但仍按照編譯結果運行。 該選項使用於適用於 為索引創建的統計信息對象、查詢謂詞中的單列以及使用 CREATE STATISTICS 語句創建的統計信息。 通常情況下,使用 同步自動更新統計信息,則設置該選項為OFF,而在以下兩種情況下,則可開啟為ON(來自官網):
  • 應用程序貧富執行相同查詢或者類似查詢,與同步統計信息更新相比,使用異步統計信息更新查詢的響應時間可以不受影響,避免出現等待最新統計信息的情況;
  • 應用程序遇到了客戶端請求超時,這些超時是由於一個或多個查詢正在等待更新後的統計信息所導致的。 在某些情況下,等待同步統計信息可能會導致應用程序因過長超時而失敗。
回到頂部(go to top)

4 何時創建與更新

4.1 創建

  • 查詢優化器自動創建
    • 創建索引時,查詢優化器自動為表格或者視圖上的索引創建統計信息
    • 在 AUTO_CREATE_STATISTICS 為 ON 時,查詢優化器為查詢謂詞中的單列創建統計信息
  • 手動執行創建
    • CREATE STATISTICS 創建

常規情況下,查詢優化器創建的統計信息就可以滿足我們的大多數需求,但是如果出現以下情況,可以考慮手動創建:

  • 數據庫引擎優化顧問建議創建
  • 查詢謂詞包含尚不位於相同索引中的多個相關列
  • 查詢從數據的子集中選擇數據
  • 查詢缺少統計信息

4.2 更新

統計信息定義在普通的表格上,當發生以下任一變化時,統計信息就會被認為是過時的,下次使用到的時候,會自動觸發更新動作:
  • - 表格從沒有數據變成大於等於1條數據;
  • - 對於數據量小於500行的表格,當統計信息的第一個字段數據累計變化量大於500以後;
  • - 對於數據量大於500行的表格,當統計信息的第一個字段數據累計變化量大於500+(20%*表格數據總量)以後。
這三種情況下,第三種情況最容易出現更新不及時的情況,比如一張100萬的表格,它最近一個月的數據增長是15萬左右,由於小於20%,統計信息沒有更新,這就導致了有關最近一個月數據sql執行有不是很正確的信息提供,那麽就需要定期去檢查並及時更新統計信息! 臨時表上可以有統計信息,其維護策略基本和普通表格一樣,但是表變量上不能建立統計信息。 技術分享
 1 --更新指定統計信息
 2 UPDATE STATISTICS Sales.SalesOrderDetail AK_SalesOrderDetail_rowguid;
 3 GO
 4 
 5 --更新表格上的所有統計信息
 6 UPDATE STATISTICS Sales.SalesOrderDetail;
 7 GO
 8 
 9 --更新整個數據庫上的所有統計信息
10 EXEC sp_updatestats;
11 
12 --刪除統計信息
13 DROP STATISTICS Purchasing.Vendor.VendorCredit, Sales.SalesOrderHeader.CustomerTotal;
14 GO
15 
16 --查看統計信息上一次更新時間
17 
18 SELECT
19        OBJECT_NAME(OBJECT_ID)
20 FROM sys.stats
21 WHERE STATS_DATE(object_id, stats_id) is not null
技術分享

參考資料:https://msdn.microsoft.com/zh-cn/library/ms174384.aspx

SQL SERVER的統計信息