为啥这个执行计划中的 Sort 算子成本这么高?
Posted
技术标签:
【中文标题】为啥这个执行计划中的 Sort 算子成本这么高?【英文标题】:Why is the cost for the Sort operator in this execution plan so high?为什么这个执行计划中的 Sort 算子成本这么高? 【发布时间】:2021-10-29 16:45:08 【问题描述】:Sort 运算符表示它只有 100 行要排序。这怎么可能比读取 190 万行更昂贵呢?我一定是读错了或误解了什么。
另外,Sort 运算符中的每次执行的估计行数 怎么只有 100?如果 Index Seek 运算符估计 Number of Rows Per Execution 为 190 万,那么只有 100 行如何通过管道传递给 Sort 运算符?
这里是查询:
DECLARE @PageIndex INT = 1000;
DECLARE @PageCount INT = 1000;
SELECT ID
FROM dbo.Table1
WHERE DateCreated >= '2021-10-27'
AND
DateCreated < '2021-10-28'
ORDER BY ID
OFFSET @PageIndex * @PageCount ROWS FETCH NEXT @PageCount ROWS ONLY
【问题讨论】:
100 是 估计的 输出行,这是由于来自OFFSET ... FETCH
的 TOP
的估计效果。它需要在输出之前对它估计为输入的全部 190 万行进行排序。
@MartinSmith 哦,这很有道理。谢谢你。后续问题:为什么只有 100 行?既然我们要取 1000,不应该是 1000 吗?
它不会嗅探变量,因此只会使用硬编码猜测。执行计划是在变量被赋值之前编译的。
该计划经过优化以适应任何@PageCount
,而不仅仅是您在此处指定的特定,猜测是100。
Side point:你可能想看看Keyset Pagination,它比你现在做的Row Pagination效率高得多
【参考方案1】:
Sort 运算符(与“Top N Sort”相对)将在返回任何行之前对其 open 方法中的整个输入进行排序。
SQL Server 估计查找将输出 190 万行进入排序。
因此,成本是对 190 万行进行排序。
你在做
OFFSET 1000000 ROWS FETCH NEXT 1000 ROWS ONLY
排序的实际输出行至少为 1,001,000 (maybe more in a parallel plan),TOP
运算符丢弃偏移量的前一百万,然后在收到要返回的 1000 后停止请求行。
100
的估计值只是一个猜测,因为 SQL Server 不知道编译计划时变量在运行时的值。
【讨论】:
以上是关于为啥这个执行计划中的 Sort 算子成本这么高?的主要内容,如果未能解决你的问题,请参考以下文章