maj*_*tor 13 sql-server paging
我想使用此方法实现表分页:
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;
Run Code Online (Sandbox Code Playgroud)
有什么我应该知道的吗?表有数百万条记录.
谢谢.
编辑:
使用建议的MAXROWS
方法一段时间后(这真的非常快)我不得不切换回ROW_NUMBER
方法,因为它具有更大的灵活性.到目前为止,我对它的速度也非常满意(我正在使用包含10列的超过1M记录的View).要使用任何类型的查询,我使用以下修改:
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
Run Code Online (Sandbox Code Playgroud)
如果您使用此过程,请确保您阻止sql注入.
Aar*_*ght 19
我实际上已经写了几次这个; ROW_NUMBER
到目前为止,它是最灵活和易于使用的,性能也很好,但对于超大型数据集而言,它并不总是最好的.SQL Server仍然需要对数据进行排序,排序可能会非常昂贵.
这里有一种不同的方法,使用几个变量,SET ROWCOUNT
并且只要你有正确的索引,它就非常快.它已经过时了,但就我所知,它仍然是效率最高的.基本上你可以做一个完全天真SELECT
的SET ROWCOUNT
,SQL Server能够优化大部分实际工作; 计划和成本最终类似于两个MAX
/ MIN
查询,这通常比单个窗口查询更快.对于非常大的数据集,其运行时间不到1/10.
话虽如此,我仍然总是建议ROW_NUMBER
当人们询问如何实现分页或分组最大值等内容时,因为它使用起来非常简单.如果你开始注意减速,我只会开始寻找上面的替代品ROW_NUMBER
.
最近,我在具有星型模式的数据仓库环境中使用了分页.当我将CTE限制为仅查询确定所需的行时,我发现性能非常好ROW_NUMBER
.我让CTE返回ROW_NUMBER
加上其他行的主键,这有助于确定行号.
在主查询中,我引用了ROW_NUMBER
for paging,然后根据CTE中的其他主键连接到其他表.我发现连接仅在满足WHERE
外部查询中的子句的行上执行,从而节省了大量时间.
归档时间: |
|
查看次数: |
20611 次 |
最近记录: |