我有一个查询,这需要我的SQL 2008数据库1.4秒。然后我试着用这个模板做子查询:MSSQL中慢速CTE子查询
;with __myResults as (
... my initial query ... already has a column:
row_number() over (ORDER BY ...) as RowNum
)
select * from __myResults where RowNum between X and Y
如果我将X和Y设置为低数字,它表现良好。大约需要0.3秒。 如果我将X和Y设置为较高的数字,则它会比初始查询更差。它在运行时不断增加,如果我增加X和Y.
这是怎么回事?
我试图做的是比较执行计划,但它们是相同的(只是在看“成本:N%”)
如何调试呢?我在哪里可以看到问题出在哪里?
我也试过如下:
where RowNum > highNumber
为快!而
where RowNum > highNumber and RowNum < highNumber + 10
很慢。最后:
where RowNum < highNumber
很慢(6秒)。
更新
我最终把结果放在一个临时表。然后做过滤。这似乎很快。
只有在您的选择查询中引用CTE时才会调用CTE。在你的where子句中设置一个低的RowNum限制它,所以它只需要做select直到它匹配,增加它意味着它将需要做更多的工作 – dbajtr
似乎使用row_number的方法被用来将结果集分割成几部分?你有没有考虑过使用[offset fetch next](https://stackoverflow.com/questions/37184267/in-sql-server-2014-order-by-clause-with-offset-fetch-next-returns-weird-results) ?它仅在sql server 2012之后才可用。 – LukStorms
CTE在结果集上执行,所以集合越大,查询越慢。 (因此 - 名称“窗口功能”)。有许多可能的解决方法,但它们取决于实际的查询。然而,我会尝试的第一件事是将包含rownumber的结果选入临时表(不是表变量),并将其用作基础而不是CTE。如上所述 - 还有其他技术可以尝试使用选择TOP和NOT IN,或者使用联合和自联接来最小化查询并优化索引。但是,如果没有实际查询,很难建议 –