SQL Server中双表去重的键集分页实现方案问询
实现两表去重UserId的键集分页方案
核心思路
利用UNION去重+单列索引加速+**键集游标(基于UserId)**实现高效分页,规避索引视图的高维护开销,同时保证页面内、页面间无重复数据。
步骤1:创建必要索引
为两张表的UserId列单独创建索引,让查询能快速筛选和扫描数据:
CREATE INDEX IX_TableA_UserId ON TableA(UserId); CREATE INDEX IX_TableB_UserId ON TableB(UserId);
步骤2:键集分页查询实现
通过传递上一页最后一个UserId作为游标(而非偏移量),每次只查询大于该游标的去重UserId,再按UserId排序取指定页大小的数据。
通用查询模板(SQL)
-- 参数说明: -- @last_user_id: 上一页返回的最后一个UserId,首次请求传对应数据类型的最小值(如正整数传0,字符串传'') -- @page_size: 每页需要返回的UserId数量 SELECT UserId FROM ( SELECT UserId FROM TableA WHERE UserId > @last_user_id UNION SELECT UserId FROM TableB WHERE UserId > @last_user_id ) AS Combined ORDER BY UserId LIMIT @page_size;
示例验证
以你提供的测试数据为例:
- 第1页(last_user_id=0,page_size=3)
查询返回:1,2,3,最后一个UserId为3 - 第2页(last_user_id=3,page_size=3)
查询返回:4,5,6,结果无重复且符合页大小要求
关键优势
- 高效无性能衰减:基于
UserId > @last_user_id的条件利用索引直接定位起始位置,不会像偏移分页那样随页数增加变慢。 - 自动去重:
UNION操作会自动剔除两表中重复的UserId,保证结果唯一性。 - 低维护开销:仅需维护单列索引,远低于索引视图的维护成本,适配数据频繁变更的场景。
API层处理逻辑
- 首次请求时,默认传入
last_user_id为对应数据类型的最小值。 - 每次返回结果后,将最后一条记录的
UserId作为下一页请求的last_user_id参数。 - 当返回的结果数量小于
page_size时,判定为最后一页。
内容的提问来源于stack exchange,提问作者Kaustabh Kakoty
相关产品推荐
相关产品推荐

