Sql server 为什么有上限的SQL Server CTE比无上限的慢

Sql server 为什么有上限的SQL Server CTE比无上限的慢,sql-server,sql-server-2008-r2,common-table-expression,database-performance,Sql Server,Sql Server 2008 R2,Common Table Expression,Database Performance,我试图找出使用SQLServer2008的分页方法之间的性能。我已使用流动查询: WITH CTE(RowNo, UniqueId) AS ( SELECT TOP (5000+100) ROW_NUMBER() OVER (ORDER BY ReceiveDate) AS RowNo, UniqueId FROM LogEntries WHERE ServerId = '111.112.113.114' ) SELECT TOP 100 CTE.RowNo,

我试图找出使用SQLServer2008的分页方法之间的性能。我已使用流动查询:

WITH CTE(RowNo, UniqueId)
AS (
    SELECT TOP (5000+100) ROW_NUMBER() OVER (ORDER BY ReceiveDate) AS RowNo, UniqueId
    FROM LogEntries
    WHERE ServerId = '111.112.113.114'
)
SELECT 
    TOP 100 CTE.RowNo, CTE.UniqueId, L.[Subject]
    FROM
        CTE
        INNER JOIN LogEntries L ON L.UniqueId = CTE.UniqueId
    WHERE
        CTE.RowNo > 5000;
SQL Server的服务器统计信息报表花了232ms完成查询。但是当我移除TOP(5000+100)时,工作完成速度快了一半(仅135毫秒)。我试了好几次,结果都一样

表LogEntries有12Mi行/3.3 GB大小

有限结果集的运行速度低于完整结果的原因是什么

在SO的建议下,我在ReceiveDate(包括ServerId)上创建了索引,下面是我的快速查询,耗时约36毫秒,无需额外订购:

WITH CTE(RowNo, UniqueId)
AS (
    SELECT TOP 5100 ROW_NUMBER() OVER (ORDER BY ReceiveDate) AS RowNo, UniqueId
    FROM LogEntries
    WHERE ServerId = '111.112.113.114'
)
SELECT 
    CTE.RowNo, CTE.UniqueId, L.[Subject]
    FROM
        CTE
        LEFT JOIN LogEntries L ON L.UniqueId = CTE.UniqueId
    WHERE
        CTE.RowNo > 5000

您已经在子结果的表中创建了一个行号,该行号要求并按顺序排列

如建议的那样,检查执行计划


而你的排名是前5000+100,这与你的cte是多余的。rowno>5000。请在5000和5100之间尝试cte.rowno。

我建议您检查这两个查询的执行计划,因为它应该清楚地显示原因。但一般来说,由于在运行这些查询之前执行DBCC DROPCLEANBUFFERS排序,TOP的成本很高,为了确保其中一个没有从缓存中获取数据。请告诉我们更多关于这个表上的索引。您是否考虑过在收件人列上有一个聚集索引?您的第一个查询没有< <代码> >“< /COD>”子句,因此它完全不能保证什么是<代码> 5100 < /代码>行返回。尽管如此,
TOP
的应用可能会改变执行计划。e、 它可能使用不同的索引或连接类型。在“以前”的日子里,有一个分页技巧,你选择了两次top以最小化分页的选择。我怀疑这与新的“公共表表达式”重复使用的模式相同。