在SQL Server 2012中获取总计数和分页的更好方法

LCJ*_*LCJ 20 sql-server pagination sql-server-2012

我要求获取记录的总数和分页.目前我在SQL Server 2012中列出如下所示.这需要一个单独的查询来获取计数.SQL Server 2012中是否有任何改进的方法?

ALTER PROCEDURE dbo.tpGetPageRecords
(
    @OffSetRowNo INT,     
    @FetchRowNo INT,
    @TotalCount INT OUT
) 
AS 

SELECT CSTNO, CSTABBR 
FROM DBATABC
WHERE CSTABBR LIKE 'A%'
ORDER BY CSTNO
OFFSET ( @OffSetRowNo-1 ) * @FetchRowNo ROWS
FETCH NEXT @FetchRowNo ROWS ONLY

SET @TotalCount = 
(SELECT COUNT(*)
FROM DBATABC
WHERE CSTABBR LIKE 'A%')


GO
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 38

如果我们允许更改合同,您可以:

SELECT CSTNO, CSTABBR,COUNT(*) OVER () as TotalCount
FROM DBATABC
WHERE CSTABBR LIKE 'A%'
ORDER BY CSTNO
OFFSET ( @OffSetRowNo-1 ) * @FetchRowNo ROWS
FETCH NEXT @FetchRowNo ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

现在,总数将作为结果集中的单独列提供.不幸的是,没有办法将此值赋给同一语句中的变量,因此我们不能再将其作为OUT参数提供.

这使用该OVER子句(自2005年起可用)允许在整个(无限制)结果集上计算聚合,而不需要GROUP.

  • 表现非常棒!! 测试表1密耳记录2268ms vs 9ms正常计数+ 68ms(实际选择仅记录100页) (7认同)
  • 看看这篇文章:[SQL Server 2005 分页 – 圣杯](https://www.sqlservercentral.com/articles/sql-server-2005-paging-%e2%80%93-the-holy-grail ),其中她/他解释了性能不佳的原因,并给出了替代方案:“在这种情况下,SQL Server 通过将所有数据转储到隐藏的假脱机表中来实现 COUNT(*) OVER(),然后聚合该表并连接回你的主要输出。” (2认同)