当我查看执行计划时,我经常将“估计行数”与“实际行数”进行比较,寻找差异。例如,当我将鼠标悬停在下图中底部的箭头上时,估计值为 1,实际值为 200,因此乍一看似乎是一个糟糕的估计。

然而,我开始怀疑这是否真的只是一次执行的估计。当我将鼠标悬停在寻求获得更多细节上时,我看到有 200 次处决,估计为 199.98。所以如果我的预感是正确的,估计实际上已经死了。

任何人都可以为我确认是否是这种情况?如果是这样,我是唯一一个认为这是令人难以置信的误导的人吗(尤其是当鼠标悬停在箭头上时)?如果有帮助,这里是设置和重现上述计划的脚本:
-- Setup: Create 2 tables with 100K rows each.
CREATE TABLE T1(Id int NOT NULL PRIMARY KEY, X INT NOT NULL)
CREATE TABLE T2(Id int NOT NULL PRIMARY KEY)
CREATE INDEX Ix ON T1 (X, Id)
;WITH
Pass0 AS (SELECT 1 AS C UNION ALL SELECT 1), --2 rows
Pass1 AS (SELECT 1 AS C FROM Pass0 AS A, Pass0 AS B),--4 rows
Pass2 AS (SELECT 1 AS C FROM Pass1 AS A ,Pass1 AS B),--16 rows
Pass3 AS (SELECT 1 AS C FROM Pass2 AS A ,Pass2 AS B),--256 rows
Pass4 AS (SELECT 1 AS C FROM Pass3 AS A ,Pass3 AS B),--65536 rows
Pass5 AS (SELECT 1 AS C FROM Pass4 AS A ,Pass2 AS B),--1048576 rows
Tally AS (SELECT ROW_NUMBER() OVER (ORDER BY C) AS Number FROM Pass5)
INSERT INTO T1
SELECT Number, Number
FROM Tally
WHERE Number <= 100000
INSERT INTO T2
SELECT Id
FROM T1
--Now join them
SELECT *
FROM T1
JOIN T2 ON T2.Id = T1.Id
WHERE T1.X <= 200
Run Code Online (Sandbox Code Playgroud)
是的,就是这种情况 - SSMS 并不总是向您显示估计的行数 * 执行次数,如果您没有像以前那样深入挖掘,这显然会导致一些不准确的假设。但从技术上讲,您的问题的答案是否定的。有时 SSMS 会得到正确的估计,这取决于运算符和其他语义。
在SentryOne 计划资源管理器中,我们尝试通过在几种情况下显示 SQL Server 的行数 * 执行次数而不是盲目地从计划 XML 中复制行数来弥补这一点。您的计划,例如:
