裡我想談下當前基數預估含有的侷限性,還有如何應用不同新技術來克服這些侷限。
上個星期你就看到,當執行計畫被編譯時,sql server使用直方圖和密度向量來作基數預估。sql server這裡使用的模型是個靜態的,它有很多的缺點和陷阱。在sql server 2014裡這些情況會改變——下個星期我會詳細講解這些提公升。
為了給你基數預估**有問題的具體例子,假設有下列2個表:orders表和country表。orders表裡的每條記錄代表客戶下的訂單(像資料倉儲情景裡的事實表),那個表裡通過外來鍵約束指向country表(它就像緯度表)。現在我們對這2個表進行乙個來自uk的銷售查詢:
1當你檢視它的執行計畫時,會發現sql server在基數預估上有個大問題。select salesamount from
country
2inner
join orders on country.id =
orders.id
3where name ='uk
'
sql server估計行數是501,實際上聚集索引查詢運算子的實際行數是1000。sql server這裡使用idx_id_salesamount統計資訊物件的密度向量來做出那個預估:密度向量是0.5(在那列我們只有2個不同值),因此估計行數是501(1001 * 0.5)。你可以通過增加過濾統計資訊物件來解決這個問題。這會給sql server更多關於資料分布本身的資訊,也會幫助基數預估。
1當你現在再次看執行計畫時,你會看到現在的估計行數和實際行數是一樣了。關於這個問題的更多資訊可以檢視這個文章:create
statistics country_uk on
country(id)
2where name ='uk
'
使用過濾統計資訊解決基數預估錯誤
。 在sql server裡對於當前的基數預估的另外乙個問題出現在查詢謂語是彼此相關的。來看下面的sql查詢:
1當我們常人來看這個查詢時,你馬上知道會有多少行返回:0!微軟公司不可能賣蘋果手機滴。當你對sql server執行這樣的查詢時,查詢優化器會獨立看每個查詢謂語:select
*from
products
2where company =
'microsoft'3
and product =
'iphone
'
在第1步裡,基數預估對謂語company = 'microsoft'完成。
在第2步裡,查詢優化器生成對另外謂語product = 'iphone'的基數預估。
最後2個預估相乘(multiplied by each other)生成最後的預估。當第1個謂語生成0.3的引數,第2個生成0.4的引數,最後的引數就是0.12(0.3 * 0.4)。查詢優化器對每個謂語各自處理,而不考慮彼此關聯。
對於這個特定問題,paul white寫了一篇非常有趣的文章
,還有你如何影響sql server的查詢優化器來生成更好效能的執行計畫。
對於sql server裡執行計畫的準確性和高效能,統計資訊和基數預估非常重要。遺憾的是它們的使用率也是有限的,尤其在一些邊緣情況。通過這篇文章你看到你如何使用過濾統計資訊幫助查詢優化器生成更好的基數預估,還有如何處理sql server裡的相關列問題。
在下星期的效能調優培訓
0831_15_基數預估問題.rar
第16周 專案1 基數排序
檔名稱 1.pp 完成日期 2015年12月14日 問題描述 驗證演算法 include include include define maxe 20 線性表中最多元素個數 define maxr 10 基數的最大取值 define maxd 8 關鍵字位數的最大取值 typedef struct ...
第16周專案1 (6)基數排序
問題及 檔名稱 1.cpp 作 者 王修文 完成日期 2016年12月15日 版 本 號 v1.0 問題描述 驗證基數排序,完成測試。輸入描述 無 程式輸出 測試資料 include include include define maxe 20 線性表中最多元素個數 define maxr 10 基...
第16周專案1 (8)基數排序
問題描述及 煙台大學計算機與控制工程學院 作 者 馬賽 完成日期 2016年12月15日 問題描述 用序列作測試資料,驗證歸基數排序 endif btree h included include include include define maxe 20 線性表中最多元素個數 define max...