目錄
基數評估... 1
說明... 2
基數評估準確的重要性... 2
模型假設... 3
啟用新的基數評估... 3
驗證基數評估的版本... 3
在遷移到新的基數評估前要測試... 4
校驗基數評估... 4
偏差問題... 4
需要手動處理的變化... 4
避免因為新的CE造成性能下降... 4
SQL Server 2014中的修改... 5
增加多個謂詞的相關性的假設... 5
修改超出統計信息范圍的評估... 5
Join評估算法修改... 5
Join包含(Containment)假設的修改... 6
不同值計數評估的變化... 7
診斷輸出... 7
新基數評估的調優方法... 8
修改數據庫兼容級別... 8
使用跟蹤標記... 8
基礎調優方法... 8
說明查詢優化器的目的是為了找出有效的執行計劃,根據cost運算,取出cost最小的計劃,作為執行計劃。其中影響cost最重要的一項就是基數評估(估計行數)。SQL Server 2014對基數評估做了修改。
基數評估準確的重要性基數評估提供以下信息:
1.響應行數評估(the distribution of data)
2.不同值個數評估(distinct value count)
3.重復值個數,作為上一級基數評估(duplicate count as input for parent Operator estimation calculations)
基數評估是通過計算統計信息的出來的結果,而統計信息通過優化器創建或者通過索引創建。
統計信息分為:頭,密度向量,直方圖。
當統計信息存在的時候基數評估器使用密度向量和直方圖來計算評估。
基數評估主要回答以下幾個問題:
1.一個或多個謂詞或過濾幾行
2.2個表之間的連接謂詞會過濾幾行
3.預計一個指定列集合中有多少不同值(distinct value)
Sql server中有2種謂詞:1.過濾謂詞,2.連接謂詞
基數評估(CE):試圖回答where,join,having這些謂詞的選擇性。也試圖回答group,distinct的不同值(distinct value)。
CE的計算從圖形執行計劃中是從右到左的,下一級的評估作為上一級計算評估的輸入。
每個執行計劃中的運算符都有評估值輸入,這個值決定了優化器使用什么算法的操作符,同時也決定了最終的執行計劃。所以如果評估出現偏差,會導致執行計劃選擇出現偏差,導致無法選出一個高效的執行計劃。
評估出現偏差會出現以下結果:
如果評估過?。?/p>
1.原本可以使用并行計劃更加有效的,現在使用串行計劃
2.不合適的join算法
3.不合適的索引選擇,和索引訪問方法
如果評估過大:
1.原本使用串行計劃更加有效,現在使用并行計劃
2.不可合適的join算法
3.不合適的索引選擇,和索引訪問方法
4.過多的內存分配
5.內存浪費和沒必要的并發
模型假設內核有以下假設:
Independence:假設,在沒有額外的相關信息之外,數據在不同的列是沒有關聯的
Uniformity:在統計信息的直方圖的step,數據分布式均勻分布在step上的。
Containment: 2個表連接,那么高密度的一定被低密度的包含。
Inclusion:如果對一列對常數過濾,那么認為這個常數數據一定存在在這個列中。
啟用新的基數評估當數據庫的兼容級別為120的時候,就是啟用了新的基數評估,默認使用新的基數評估。
但是可以通過查詢跟蹤標記來指定:
2312:在兼容級別低于120的時候使用新的基數評估
9481:在兼容級別在120下,使用老的基數評估
驗證基數評估的版本可以從圖形執行計劃或者xml執行計劃中找到CardinalityEstimationModelVersion,如果為120就是新的基數評估,70就是老的基數評估。
新的基數評估雖然總體提示了性能,但是對個別查詢來說,會被影響,性能變差,所以要測試。
1.在類似生產環境下,測試大多數的負荷
2.可以先遷移到sql server 2014,但是使用不運行在120兼容級別
3.也可以到120兼容級別,但是在全局范圍開9481跟蹤標記
4.新建數據庫推薦使用默認會使用120兼容級別。
校驗基數評估沒有什么特別的就是通過實際值和評估值對個對比。
偏差問題評估值偏差,是存在的,那么多少算是偏差太大了?其實沒有一個固定的值,主要是看以下2點:
1.偏差是不是造成了資源過度使用
2.偏差是不是造成了特定查詢的性能問題
如果任意一個出現問題的話,那么就能認為偏差太大了。
需要手動處理的變化只有評估值變化的情況下,看性能是否下降超過預期,如果超過要進行手動干預。
如果評估值和老CE一樣,并且計劃沒有什么變化,就不需要處理。
避免因為新的CE造成性能下降1.能夠從新基數評估得到性能優化的查詢,就使用新基數評估,其他的進行重新調整。
2.有好處的查詢使用新的基數評估,其他的使用跟蹤標記9481
3.使用老的基數評估,特定的查詢可以指定跟蹤標記2312
4.直接調試有問題的sql
5.使用老的基數評估
SQL Server 2014中的修改增加多個謂詞的相關性的假設在沒有多列統計信息的情況下,SQL Server優化器會認為謂詞之間是不相關的。
老的基數評估:各個謂詞的選擇度相乘
新的基數評估:選擇度從低到高排序,然后使用以下公式:
如果超出統計信息范圍,那么老的基數評估就認為不存在,評估行數為1。
新的基數評估會用,密度*總行數來當評估。
Join評估算法修改簡單Join老的基數評估是以線性增長的方式一步一步對齊2個直方圖。(根本不知道是怎么玩的)
新的基數評估,使用相對簡單的join評估算法,只是用直方圖的最大最小邊界來對齊。(文章并沒有給出詳細的算法很坑爹)。
新的基數評估是用這種原則,很容易發現評估值不夠準確。
多Join條件多個join條件,對于老的基數評估來說,是獨立的謂詞,是用選擇度相乘的方法來組合。
新的基數評估,是用2個不同值個數(distinct value count)中較小的一個,然后乘以2邊的平均頻率。(搞不懂)
Join帶相等和不相等的謂詞老的基數評估,是獨立的謂詞,是用選擇度相乘的方法來組合。
新的基數評估,認為大表小標多對1的關系。即大表中的一行,必定存在于表的一樣與之對應。這個算法把大表的評估作為評估。(這個簡單)
Join包含(Containment)假設的修改如果是等值連接,那么就會假設這個列表2邊都是存在的。如果存在join表上有非join謂詞,老的基數評估那么會認為一些級別的相關,這種相關叫做簡單包含(Simple Containment)。
老的基數評估的JOIN評估,假設在使用join謂詞之前,任意存在的謂詞會縮小直方圖,而謂詞之間是不相關的。老CE用這樣的評估方式會讓評估值偏大。
USE [AdventureWorks2012];
GO
SELECT [od].[SalesOrderID], [od].[SalesOrderDetailID]
FROM Sales.[SalesOrderDetail] AS [od]
INNER JOIN PRoduction.[Product] AS [p]
ON [od].[ProductID] = [p].[ProductID]
WHERE [p].[Color] = 'Red' AND
[od].[ModifiedDate] = '2008-06-29 00:00:00.000'
OPTION (QUERYTRACEON 9481); -- CardinalityEstimationModelVersion 70
新的基數評估是使用基本包含(Base Containment),新的基數評估,是直接從基表上面獲取選擇度,而不是經過謂詞過濾之后。
對于新的基數評估和老的相比在多對多連接中,不同值計數評估相差很小。如果join條件會放大基數,老的基數評估可能會不準確。
新的基數評估根據join謂詞和非join謂詞選擇不同值。新的基數評估使用環境基數(ambient cardinality),環境基數是group by或者distinct列的最小不同值集合(The new CE uses “ambient cardinality”, which is the cardinality of the smallest set of joins that contains the GROUP BY or DISTINCT columns.)。
診斷輸出使用新的xevent,query_optimizer_estimate_cardinality來輸出
CREATE EVENT session [CardinalityEstimate] ON SERVER
ADD EVENT sqlserver.query_optimizer_estimate_cardinality
ADD TARGET package0.event_file( SET filename = N'S:/CE/CE_Data.xel' ,
新聞熱點
疑難解答