我有两个具有以下架构的表:
-
Table A
:ColumnA, UserId,
... - 为简洁起见,省略了架构的其余部分 -
Table B
:ColumnB, UserId,
... - 为简洁起见,省略了架构的其余部分
表之间可以有重复的值。例如 - 表 A 行 (<some-columnA-value>, 1, ...)
和表 B 行 (<some-columnB-value>, 1, ...)
, 1 是 UserId。
现在,我有一个 API,用于获取所有 UserId
两个表中的值。随着数据的增加,我现在想为此 API 使用分页,并希望相应地修改查询。页面之间或页面内也不应该有任何重复项。
我该如何实现这一目标?还有一个要求是我需要使用键集分页而不是偏移分页,因为当偏移量增加时,偏移分页会变慢。
到目前为止,我已经考虑过使用索引 View ,因为我只需要获取 1 列,但由于数据不断频繁且大量地变化,维护索引 View 的开销并不是最佳的。
表A:
表B:
结果(如果没有页面大小):
结果(如果页面大小为 3)
第 1 页
第 2 页
最佳答案
正如我在 my canonical post on Keyset Pagination 中提到的(按键分页),基础查询需要高效。
在你的例子中,关键(原文如此)是使用合并联盟,按ID分组,然后取前3个。这意味着分组是在已经排序的集合上进行的,并且可以使用流聚合。
因此,首先将表UNION ALL
组合在一起,然后GROUP BY UserId
最终结果并取TOP (3)
。
SELECT TOP (3)
t.UserId
FROM (
SELECT a.UserId
FROM TableA a
UNION ALL
SELECT b.UserId
FROM TableB b
) t
GROUP BY t.UserId
ORDER BY UserId;
最终的查询计划非常漂亮和整洁。请注意,工会在后期阶段保持正确的顺序。
正如我提到的,您需要保留之前的最高 ID 值,并将其传递给下一个查询。将其放入联合体的两半中。
SELECT TOP (3)
t.UserId
FROM (
SELECT a.UserId
FROM TableA a
WHERE a.UserId > @previousId
UNION ALL
SELECT b.UserId
FROM TableB b
WHERE b.UserId > @previousId
) t
GROUP BY t.UserId
ORDER BY UserId;
关于sql-server - SQL Server 中两个表的分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77565466/