友
我已经在我的SP中实现了分页 -
with MyData As (
select ROW_NUMBER() over (order by somecolumn desc) AS [Row],
x,y,z,...
)
Select x,y,z,...
From MyData
Where [Row] between ((@currentPage - 1) * @pageSize + 1) and (@currentPage*@pageSize)
这里的问题是,如果with
子句返回较小的行数,则会非常快地重试数据,但是当有数百万条记录时需要很长时间。有时会超时。
还有其他选择吗?
感谢您分享宝贵的时间。
答案 0 :(得分:1)
SQL服务器优化是一个非常广泛的主题,使用您发布的有限信息来解决问题几乎是不可能的。但是,由于您急于寻求解决方案 - 首先,我建议您检查实际执行计划,在此处发布,并确保实际使用索引 - 如果不是这样的话然后考虑使用FASTFIRSTROW表提示强制使用索引 - 检查here和here如何改进事物,here如何使事情变得更糟。
接下来考虑的是SQL参数嗅探 - 它不太可能来自你所说的但可能在这里查看详细信息enter link description here
为了获得大规模的性能提升,您可能需要至少查看体系结构更改,确保事务日志与数据位于不同的磁盘上。将数据库文件与日志文件分开的原因是因为数据库访问是随机和日志访问是顺序的。最佳实践要求您不要在同一磁盘上混用这两种I / O类型
此外,如果你有数百万行,那么你真的需要考虑在多个磁盘上拆分数据。
最后,我强烈考虑分区表或索引see here for a start
答案 1 :(得分:1)
您的查询速度慢的原因是您在每个请求上都有排序整个表。为了显着加快速度,您需要避免以CPU,HDD /内存或分页逻辑限制为代价来分类大量数据。
由于没有太多关于你如何对表进行排序的信息,以及你是否经常插入中间/删除条目,我会通过做出这些假设来缩小你的问题:
我想你会有一个存储文章存档的表格。新条目大多位于表格的底部,表格中间的条目很少被删除。
您始终按相同的列somecolumn
排序,并按相同的顺序排序,例如降。
您没有任何用户输入过滤器(如文章标题或作者)。
这使得表格在输出方面是静态的:除非插入新文章,否则每篇文章都在同一个地方。新的一个出现在输出的顶部。然后,您可以将ROW_NUMBER() OVER ()
存储为列。更方便的解决方案是IDENTITY
列。如果您在此列上创建聚簇索引,它将加快速度。
alter table add [Record_Number] int null IDENTITY
此新列添加为null
,因此您可以首次填充值。然后你可以not null
。
另一方面,您可以通过
非常快地获得行号select @Max_Row = SELECT MAX(row_number) from MyTable
现在,当您拥有总行数,页面大小和页码时,您可以在一个语句中选择所需的行,而无需对整批进行排序。
Select * From MyTable
Where row_number between
(@Max_Row - @Page * @Page_Size) + 1 AND
@Max_Row -(@Page - 1) * @Page_Size
如果您的CTE中有过滤器,那么请提供一些有关数据结构的更多信息,以便我们考虑一种限制CTE范围的方法。