在SQL Server 2000、2005、2008、2012中分页结果的最佳方法(性能方面)是什么?如果你还想获得结果的总数(在分页之前)?


当前回答

   CREATE view vw_sppb_part_listsource as 
    select row_number() over (partition by sppb_part.init_id order by sppb_part.sppb_part_id asc ) as idx, * from (
      select 
          part.SPPB_PART_ID
          , 0 as is_rev
          , part.part_number 
          , part.init_id 
      from t_sppb_init_part part 
      left join t_sppb_init_partrev prev on ( part.SPPB_PART_ID = prev.SPPB_PART_ID )
      where prev.SPPB_PART_ID is null 
      union 
      select 
          part.SPPB_PART_ID
          , 1 as is_rev
          , prev.part_number 
          , part.init_id 
      from t_sppb_init_part part 
      inner join t_sppb_init_partrev prev on ( part.SPPB_PART_ID = prev.SPPB_PART_ID )
    ) sppb_part

当涉及到不同的init_id时会重新启动idx吗

其他回答

您没有指定使用的语言或驱动程序。因此我只是抽象地描述它。

创建可滚动的结果集/数据集。这要求在表上有一个(多个)主表 跳到最后 请求行数 跳转到页面的开头 滚动行直到页面的末尾

从2012年起,我们可以使用 偏移10行只获取下10行

获取结果总数和分页是两个不同的操作。对于这个示例,让我们假设您正在处理的查询是

SELECT * FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate

在这种情况下,您将使用以下命令确定结果的总数:

SELECT COUNT(*) FROM Orders WHERE OrderDate >= '1980-01-01'

...这可能看起来效率很低,但实际上性能很好,假设所有索引等都正确设置。

接下来,要以分页方式返回实际结果,下面的查询将是最有效的:

SELECT  *
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *
          FROM      Orders
          WHERE     OrderDate >= '1980-01-01'
        ) AS RowConstrainedResult
WHERE   RowNum >= 1
    AND RowNum < 20
ORDER BY RowNum

这将返回原始查询的第1-19行。这里很酷的事情是,尤其是对于web应用程序,你不需要保留任何状态,除了要返回的行号。

用例方面,以下内容似乎易于使用和快速。只需设置页码。

use AdventureWorks
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6;
with result as(
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail
where 1=1
)
select SalesOrderDetailID, SalesOrderID, ProductID from result
WHERE result.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)

同样没有CTE

use AdventureWorks
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6
SELECT SalesOrderDetailID, SalesOrderID, ProductID
FROM (
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail
where 1=1
 ) AS SOD
WHERE SOD.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)

create PROCEDURE SP_Company_List (@pagesize int= -1,@pageindex int= 0) 选择Id, NameEn从公司订单的Id ASC OFFSET (@pageindex-1)* @pagesize ROWS FETCH NEXt @pagesize ROWS ONLY END GO 声明@return_value int EXEC @return_value = [dbo]。[SP_Company_List] @pagesize = 1, > @pageindex = 2 SELECT 'Return Value' = @return_value 去