Sql-Server

嵌套循環估計太低,導致 tempdb 溢出

  • May 23, 2018

我正在調整查詢,我認為現在的主要問題是早期有一個嵌套循環步驟,行估計太低,導致分配的記憶體太少,下游步驟溢出臨時數據庫。麻煩的步驟是下面綠色框中的步驟。

計劃

https://www.brentozar.com/pastetheplan/?id=Sk8E-6YAM

嵌套循環的兩個輸入都具有 240 萬行的準確行估計,但該步驟的輸出估計只有 37 行,而實際為 240 萬行。

以下所有三個 Table Spool 步驟的估計值與實際值也完全相同,這讓我認為他們是從嵌套循環中獲得估計值的。在排序步驟中,每個分支都會溢出到 tempdb。

我在想,如果我能從嵌套循環中糾正估計的行,它不僅可以防止頂部分支上的溢出,而且 Table Spools 還將繼承正確的估計,獲得足夠的記憶體授予,並且不溢出。

開啟舊版 CE 的 SQL Server 2016 SP2。

這是查詢

SELECT  Object18.Column1,
       Object18.Column3,
       Function1(Object19.Column12) AS Column13,
       Function2(Object19.Column12) AS Column14,
       Function3(DISTINCT (CASE WHEN Object19.Column15 = ? THEN Object18.Column6 END)) AS Column16,
       Function3(DISTINCT (CASE WHEN Object19.Column17 = ? THEN Object18.Column6 END)) AS Column18,
       Function3(DISTINCT Object18.Column6) AS Column19
from Object8 Object18
join Object20 Object19 on Object19.Column20 = Object18.Column7 and Object19.Column3 = Object18.Column3
where Object19.Column8 = ?
GROUP BY Object18.Column1, Object18.Column3
option (recompile)

插入後,我能夠通過在臨時表上創建索引來更正估計值。這解決了 tempdb 溢出問題,但性能並沒有太大改善。最終,將數據查詢從聚合中分離出來,並將其他一些查詢打亂,以獲得最大的並行化優勢,從而將速度降低了 4 倍。謝謝大家,尤其是喬·奧比什

引用自:https://dba.stackexchange.com/questions/206905