為什麼串聯運算符估計的行數少於其輸入?
在下面的查詢計劃片段中,顯然
Concatenation
運算符的行估計應該是~4.3 billion rows
,或者它的兩個輸入的行估計的總和。但是,會產生一個估計值,從而導致將數百 GB 的數據溢出到 tempdb
~238 million rows
的次優Sort
/策略。Stream Aggregate
在這種情況下,邏輯上一致的估計會產生Hash Aggregate
,消除溢出,並顯著提高查詢性能。這是 SQL Server 2014 中的錯誤嗎?是否存在任何有效情況下低於輸入的估計值可能是合理的?可能有哪些解決方法?
這是完整的查詢計劃(匿名)。我沒有對此伺服器的系統管理員訪問權限,無法提供來自
QUERYTRACEON 2363
或類似跟踪標誌的輸出,但如果有幫助,我可以從管理員那裡獲取這些輸出。該數據庫的兼容性級別為 120,因此使用新的 SQL Server 2014 基數估計器。
每次載入數據時都會手動更新統計資訊。鑑於數據量,我們目前使用預設採樣率。較高的採樣率(或
FULLSCAN
)可能會產生影響。
引用 Campbell Fraser 在此 Connect 項目上的話:
這些“基數不一致”可能出現在許多情況下,包括使用 concat 時。它們可能會出現,因為最終計劃中特定子樹的估計可能是在結構不同但邏輯上等效的子樹上執行的。由於基數估計的統計性質,不能保證對不同但邏輯等效的樹進行估計得到相同的估計。所以總體上沒有提供預期一致性的保證。
稍微擴展一下:我喜歡解釋的方式是說初始基數估計(在基於成本的優化開始之前執行)產生更“一致”的基數估計,因為整個初始樹都被處理,每個後續估計直接取決於前一個。
在基於成本的優化過程中,可以探索計劃樹的部分(一個或多個運算符)並用備選方案替換,每個備選方案都可能需要新的基數估計。沒有一般的方法可以說哪個估計通常會比另一個更好,因此很有可能最終得出一個看起來“不一致”的最終計劃。這只是將“一些計劃”拼接在一起形成最終安排的結果。
綜上所述,SQL Server 2014 中引入的新基數估計器 (CE) 進行了一些詳細的更改,這使得這種情況與原始 CE 的情況相比不太常見*。*
除了升級到最新的累積更新並檢查 4199 的優化器修復是否已啟用之外,您的主要選擇是嘗試統計/索引更改(注意缺少索引的警告)和更新,或者以不同的方式表達查詢。目標是獲得一個顯示您需要的行為的計劃。例如,這可能會被計劃指南凍結。
匿名計劃很難評估細節,但我也會仔細查看點陣圖,看看它們是“優化”(Opt_Bitmap)還是優化後(Bitmap)種類。我也懷疑過濾器。
但是,如果行數準確無誤,這似乎是一個可能從列儲存中受益的查詢。除了通常的好處之外,您還可以利用批處理模式操作員的動態記憶體授予(可能需要跟踪標誌 9389 )。