【发布时间】:2013-02-24 21:03:06
【问题描述】:
我正在使用 SQL Server 2008 和以下查询从我们的 JSF 应用程序中实现分页数据检索,在下面的代码中,我一次 检索 25 行,按默认排序进行排序按 DESC 顺序排列的列。
SELECT * FROM
(
SELECT TOP 25 * FROM
(
SELECT TOP 25 ...... WHERE CONDITIONS
--ORDER BY ... DESC
)AS INNERQUERY ORDER BY INNERQUERY.... ASC
)
AS OUTERQUERY
ORDER BY OUTERQUERY.... DESC
它有效,但有一个明显的流程。如果用户请求查看最后一页,并且表中有超过 1000 万条记录,则 second TOP Query 必须首先查看 retrieve the 10 million 记录,然后才是first top Query 会挑选出Top 25,看起来像:
SELECT * FROM
(
SELECT TOP 25 * FROM
(
SELECT TOP 10000000 ...... WHERE CONDITIONS
--ORDER BY ... DESC
)AS INNERQUERY ORDER BY INNERQUERY.... ASC
)
AS OUTERQUERY
ORDER BY OUTERQUERY.... DESC
我考虑用 ROW_NUMBER OVER(....) 替换上面的内容,但似乎我遇到了同样的问题,第二个 TOP 语句必须得到整个结果,然后你才能执行where ROW_NUMBER between x and y。
您能否指出我在上述方法中的错误以及如何优化它的提示?
【问题讨论】:
-
这是一个很好的 row_number 示例,您可能会发现它很有用:blogs.x2line.com/al/archive/2005/11/18/1323.aspx
-
感谢您的链接,我看了看,但正如您自己所见,第一个 SELECT 语句将检索所有行,然后您才能在第二个 SELECT 中使用
between x and y选择一个范围。我的问题是第一个 Select 语句需要一段时间才能返回,因为记录很多。 -
查看这个 SO 链接及其对 Greg Hamilton 的文章“A More Efficient Method for Paging Through Large Result Sets”stackoverflow.com/questions/2308220/… 的引用
-
顺便说一句,很多时候问题是试图为用户提供一些不是绝对必要、有用或合理的东西(是的,我知道用户一直在问这种事情!) .没有人会以 25 行(也不是 500 行)为一组翻阅 1000 万行。他会在第 1000 次迭代之前饿死。那么,如果他真的需要,为什么不提供从头到尾的分页呢?你能让他明白他在问一些疯狂的事情吗?我通常会说服我的客户对他们的查询有这种明显的限制。
-
大多数客户通常接受的一个选项是能够更改订单,或具有某种过滤器,或两者兼而有之,并将他们的分页限制为 1000 或 2000 个第一条记录。您处于最糟糕的情况:不断变化的数据、大表和非聚集索引……哎哟!这避免了维护辅助表或结构来帮助查询。维护您的非聚集索引以尽可能避免碎片化也很重要。
标签: sql sql-server-2008