SQL Server 2008分页行检索和大表

时间:2012-03-22 23:55:34

标签: sql sql-server-2008

我正在使用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

请您指出我在上述方法中的错误,并提示如何优化它?

2 个答案:

答案 0 :(得分:0)

我目前正在使用以下代码来检索行的子集:

WITH PAGED_QRY (
                   SELECT *, ROW_NUMVER() OVER(ORDER BY Y) AS ROW_NO
                   FROM TABLE WHERE ....
               ) 
SELECT * FROM PAGED_QRY WHERE ROW_NO BETWEEN @CURRENT_INDEX and @ ROWS_TO_RETRIEVE
ORDER BY ROW_NO

其中@current_index@rows_to_retrieve (即。150是您的分页变量。它更干净,更容易阅读。

我也尝试使用SET ROW_COUNT @ROWS_TO_RETRIEVE,但似乎没有太大区别。

使用上面的查询并仔细研究查询的执行路径并修改/创建索引和统计数据,我已经达到了足够令人满意的结果,因此我将其作为答案。在内部查询中仅检索所需行的最初目标似乎是不可能的,如果您确实找到了方法,请告诉我。

答案 1 :(得分:0)

我们可以更多地改进上面的查询。 如果我假设@current_index是当前页码,那么我们可以将上述查询重写为:

WITH PAGED_QRY (
               SELECT top (@current_index * @rows_to_retrieve) *, ROW_NUMVER() 
                 OVER(ORDER BY Y) AS ROW_NO
               FROM TABLE WHERE ....
           ) 
 SELECT TOP @ROWS_TO_RETRIEVE FROM PAGED_QRY
 ORDER BY ROW_NO DESC

在这种情况下,我们的内部查询不会返回整个记录集。假设我们的page_index是3& page_size是50,那么它将只选择150行(即使我们的表包含数百/数千/数百万行)&我们也可以跳过where子句。