1

我有一个查询,这需要我的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秒)。

更新

我最终把结果放在一个临时表。然后做过滤。这似乎很快。

+0

只有在您的选择查询中引用CTE时才会调用CTE。在你的where子句中设置一个低的RowNum限制它,所以它只需要做select直到它匹配,增加它意味着它将需要做更多的工作 – dbajtr

+0

似乎使用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

+0

CTE在结果集上执行,所以集合越大,查询越慢。 (因此 - 名称“窗口功能”)。有许多可能的解决方法,但它们取决于实际的查询。然而,我会尝试的第一件事是将包含rownumber的结果选入临时表(不是表变量),并将其用作基础而不是CTE。如上所述 - 还有其他技术可以尝试使用选择TOP和NOT IN,或者使用联合和自联接来最小化查询并优化索引。但是,如果没有实际查询,很难建议 –

回答

0

为什么不使用FETCH/OFFSET

select * 
from __myResults 
order by ?? 
offset X - 1 
fetch next (X - Y) rows only; 

您需要调整参数XY

+0

感谢您的反馈。我只是意识到,我们必须支持MS SQL 2008 :( – ims1234

+0

我只是测试它,现在所需的最大时间,不比最初的查询慢!谢谢。所以这可能是可以理解的,整个查询必须扫描即使正在使用偏移量 – ims1234

+0

@ ims1234 ...您是否在'order by'列中有索引? –