SSMS 执行计划中的每次执行是否总是“估​​计行数”?

Joh*_*nyM 7 sql-server ssms

当我查看执行计划时,我经常将“估计行数”与“实际行数”进行比较,寻找差异。例如,当我将鼠标悬停在下图中底部的箭头上时,估计值为 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)

Aar*_*and 7

是的,就是这种情况 - SSMS 并不总是向您显示估计的行数 * 执行次数,如果您没有像以前那样深入挖掘,这显然会导致一些不准确的假设。但从技术上讲,您的问题的答案是否定的。有时 SSMS 会得到正确的估计,这取决于运算符和其他语义。

SentryOne 计划资源管理器中,我们尝试通过在几种情况下显示 SQL Server 的行数 * 执行次数而不是盲目地从计划 XML 中复制行数来弥补这一点。您的计划,例如:

在此处输入图片说明