Sql-Server

嵌套循環運算符使用什麼方法/公式進行行估計?

  • September 9, 2020

AdventureWorks 中的以下簡單查詢:

SELECT  *
FROM    Person.Person p
       JOIN HumanResources.Employee e
           ON p.BusinessEntityID = e.BusinessEntityID

給出以下執行計劃:

新的估算計劃

如果我查看上面的計劃,我可以看到索引掃描和索引搜尋都(正確地)估計 290 行,但是,連接兩者的估計循環運算符估計 279 行。

舊估算器

舊的估計器也正確地從查找和掃描中猜測了 290 行,但嵌套循環估計了 289 行,在這個查詢的情況下這是一個更好的估計。

那麼,對於新的 CE,優化器估計當它連接來自索引掃描的 290 行和來自索引查找的 290 行時,是否會有 11 行不匹配?

它使用什麼方法/公式進行估算?

我是否正確地說無論所說的方法是什麼,它已經從早期的 CE 版本改變,因為它做出了不同的估計?

我意識到新 CE 的“壞”估計不足以影響性能,我只是想了解估計器的處理

SQL Server 估計聯接的基數,而不是物理運算符。無論採用何種物理運算符(散列、合併、嵌套循環或應用),所討論的內部連接都將具有相同的估計值。物理運算符可能會影響顯示,但邏輯連接的選擇性是一樣的。

除此之外,邏輯連接估計仍然是一個複雜的話題。有許多有效的方法來產生估計。Dimitry Piliugin在 SQL Server 的 Join Estimation Internals 中很好地介紹了兩個主要的替代方案。您還可以在 Microsoft 論文Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimator中找到原始 CE 模型和最新 CE 模型之間的一般差異。

使用直方圖估計連接選擇性時,會出現一個主要區別。更新的 CE 模型使用粗略對齊,正如我在SQL Server Join Estimation using Histogram Coarse Alignment中所描述的那樣。最初的 CE 對每一步都使用了線性插值的精細對齊,這樣可以提供更準確的估計,但也可以更加可變。

您可能會注意到,使用 Simple Join(帶有 Dima 給出的跟踪標誌 9479)為您的測試查詢提供了“完美”的估計。

有一個 TF 會強制優化器使用 Simple Join 算法,即使直方圖可用。我會給你這個用於測試和教育目的。

在其他(更常見的)情況下,簡單的連接會產生糟糕的結果。這就是基數估計的本質。

有關的:

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