Sql-Server
嵌套循環估計太低,導致 tempdb 溢出
我正在調整查詢,我認為現在的主要問題是早期有一個嵌套循環步驟,行估計太低,導致分配的記憶體太少,下游步驟溢出臨時數據庫。麻煩的步驟是下面綠色框中的步驟。
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 倍。謝謝大家,尤其是喬·奧比什