【问题标题】:Efficient pagination in SQL Server 2008 R2SQL Server 2008 R2 中的高效分页
【发布时间】:2014-08-02 22:05:08
【问题描述】:

我想编写一个执行以下操作的存储过程: * 返回匹配查询的记录数(确定向用户显示的页数) * 从当前页面的查询中返回具有特定记录子集的另一个记录集。

从我在 StackOverflow 上找到的另一个问题(对不起,我丢失了链接),我发现我们是这样进行分页的:

SELECT u.* FROM 
(
    SELECT t.*, ROW_NUMBER() OVER (ORDER BY t.id) as rownum FROM
    (
        [obscenely long select query]
    )
    as t
)
AS u WHERE u.rowNum >= 1 AND u.rowNum <= 20

我可以通过执行以下操作来获取 [obscenely long select query] 返回的记录数:

SELECT COUNT(*) AS numRecords from ([obscenely long select query]) AS records

我想尽可能有效地获取这两个记录集。

我能弄清楚如何做到这一点的唯一方法是将上面的两个语句都放入一个存储过程中。由于以下几个原因,这让我觉得效率低下:

  • 我必须写出 [obscenely long select query] 两次,使解决方案更难维护/更改(我真的想避免这种情况,如果可能的话)。
  • 我必须运行 [obscenely long select query],获取所有可能的记录(可能是数千条记录),然后再将其缩减到合理的分页大小,然后在获取计数时再次运行。

我尝试过的其他解决方案:

  • 将 [obscenely long select query] 放入自己的存储过程中(这会导致语法错误)。

有什么可以做的吗?我应该接受它并坚持我目前的解决方案,还是有更优雅的方法来解决这个问题?

【问题讨论】:

    标签: sql sql-server sql-server-2008 sql-server-2008-r2 pagination


    【解决方案1】:

    根据[obscenely long select query] 结构,您可以使用临时表或表变量:
    - 用匹配行的 id 填充临时表
    - 计算临时表行数以计算页数
    - 为调用者检索结果,使用与相关数据库表连接的临时表构建查询

    【讨论】:

    • 我认为这可能有效。我会玩一下临时表,看看我能做什么。谢谢!
    【解决方案2】:

    实现分页的一种解决方案是:

    您的存储过程将遵循参数

    @PageSize INT,
    @PageNumbers INT
    
    ;WITH CTE AS(
            SELECT a,
                   b,
                    ROW_NUMBER() OVER(ORDER BY a) RN
            FROM    TableName
    )
    SELECT  *
    FROM    CTE
    WHERE   RN  BETWEEN ((@PageNumbers - 1) * @PageSize + 1) AND (@PageNumbers * @PageSize)
    

    如果您传递@PageNumbers = 1 和@PageSize = 10 那么

    ((@PageNumbers - 1) * @PageSize + 1) = ((1 - 1) * 10 + 1) = 1
    and (@PageNumbers * @PageSize) = (1 * 10) = 10
    

    同样,如果@PageNumbers = 2 那么

    ((@PageNumbers - 1) * @PageSize + 1) = ((2 - 1) * 10 + 1) = 11
    and (@PageNumbers * @PageSize) = (2 * 10) = 20
    

    您甚至可以在您的 SP 中硬编码 @PageSize 值。

    【讨论】:

      猜你喜欢
      • 2011-06-19
      • 1970-01-01
      • 2016-01-21
      • 1970-01-01
      • 2023-04-03
      • 2011-01-27
      • 2019-04-03
      • 1970-01-01
      • 2015-08-01
      相关资源
      最近更新 更多