sql-server – 使用Row_Number在Sql Server 2008中实现表分页是否有任何性能问题?

前端之家收集整理的这篇文章主要介绍了sql-server – 使用Row_Number在Sql Server 2008中实现表分页是否有任何性能问题?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想使用这种方法实现表分页
SET @PageNum = 2;
SET @PageSize = 10;

WITH OrdersRN AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY OrderDate,OrderID) AS RowNum,*
      FROM dbo.Orders
)

SELECT * 
  FROM OrdersRN
 WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 
                  AND @PageNum * @PageSize
 ORDER BY OrderDate,OrderID;

有什么我应该注意的吗?
表有数百万条记录.

谢谢.

编辑:
在使用建议的MAXROWS方法一段时间后(真的很快),由于其灵活性更高,所以我不得不重新选择ROW_NUMBER方法.目前为止,我的速度也很高兴(我正在使用View,其中有10条记录的1M记录).要使用任何类型的查询,我使用以下修改

PROCEDURE [dbo].[PageSelect] 
(
  @sql nvarchar(512),@OrderBy nvarchar(128) = 'Id',@PageNum int = 1,@PageSize int = 0    
)
AS
BEGIN
SET NOCOUNT ON

 Declare @tsql as nvarchar(1024)
 Declare @i int,@j int

 if (@PageSize <= 0) OR (@PageSize > 10000)
  SET @PageSize = 10000  -- never return more then 10K records

 SET @i = (@PageNum - 1) * @PageSize + 1 
 SET @j = @PageNum * @PageSize

 SET @tsql = 
 'WITH MyTableOrViewRN AS
 (
  SELECT ROW_NUMBER() OVER(ORDER BY ' + @OrderBy + ') AS RowNum,*
    FROM MyTableOrView
    WHERE ' + @sql  + '

 )
 SELECT * 
  FROM MyTableOrViewRN 
  WHERE RowNum BETWEEN ' + CAST(@i as varchar) + ' AND ' + cast(@j as varchar)

 exec(@tsql)
END

如果您使用此过程,请确保您阻止了sql注入.

解决方法

我已经写过几次了到目前为止,ROW_NUMBER是最灵活和易于使用的,性能是好的,但对于非常大的数据集,并不总是最好的. sql Server仍然需要对数据进行排序,排序可能会变得相当昂贵.

有一个different approach here使用了几个变量和SET ROWCOUNT,并且非常快,只要你有正确的索引.这是老的,但据我所知,它仍然是最有效率的.基本上你可以用SET ROWCOUNT做一个完全天真的SELECT,sql Server能够优化大部分的实际工作;计划和成本最终类似于两个MAX / MIN查询,通常比单个窗口查询快很多.对于非常大的数据集,运行时间不到1/10.

话虽如此,我仍然总是推荐ROW_NUMBER,当人们询问如何实现分页或分组最大值时,因为使用起来容易多了.如果您开始注意到ROW_NUMBER的放缓,我将只开始考虑上述替代方案.

猜你在找的MsSQL相关文章