【无标题】

DB2 三种分页方案完整版对比(含原理+SQL实现+优缺点+选型)

一、三种分页方式汇总

  1. ROW_NUMBER() 行号分页(老版本通用)

  2. OFFSET FETCH 偏移分页(DB29.7+标准)

  3. Keyset 键集分页/游标分页(大数据最优)

二、完整实现 SQL

  1. ROW_NUMBER() 分页

-- 通用写法,必须加ORDER BY

SELECT * FROM (

SELECT t.*,ROW_NUMBER() OVER(ORDER BY id DESC) rn

FROM table_name t

) temp

WHERE rn BETWEEN ? AND ?;

参数:起始行、结束行

  1. OFFSET FETCH 分页(DB2推荐简洁写法)

SELECT * FROM table_name

ORDER BY id DESC

OFFSET ? ROWS FETCH NEXT ? ROWS ONLY;

参数:页码偏移量、每页条数

  1. Keyset 键集分页(高性能最优)

第一页

SELECT * FROM table_name

ORDER BY create_time DESC,id DESC

FETCH NEXT 10 ROWS ONLY;

下一页(传上一页最后一条:最后时间+最后主键ID)

SELECT * FROM table_name

WHERE create_time < ?

OR (create_time = ? AND id < ?)

ORDER BY create_time DESC,id DESC

FETCH NEXT 10 ROWS ONLY;

三、全方位对比表

对比项 ROW_NUMBER行号分页 OFFSET FETCH偏移分页 Keyset键集分页

支持版本 DB2全版本兼容 DB2 9.7及以上 全版本都支持

实现难度 中等,嵌套多层 极低,尾部追加 中等,前端传锚点值

分页参数 开始行、结束行 pageNum、pageSize 上页最后一条排序字段值

底层原理 全结果集生成行号再过滤 数据库跳过前置行数取数据 利用索引范围定位,直接截取

深分页性能 极差,越往后越慢 差,偏移越大越慢 顶级,深浅分页速度一致

索引利用率 低,易走全表排序 中,大偏移失效 极高,纯索引检索

数据稳定性 易重复、漏数据 易重复、漏数据 几乎无重复无遗漏

能否跳页 支持任意页码跳转 支持任意页码跳转 仅支持上一页/下一页,不支持直达

内存消耗 高,生成临时行号集 中 极低

业务适配 老项目兼容、小数据 中小型列表、后台管理 大数据列表、APP/前端信息流

排序要求 必须指定OVER内排序 必须整体ORDER BY 必须带唯一主键联合排序

四、各自优缺点

  1. ROW_NUMBER 分页

优点

• 兼容DB28、9等老旧版本,无版本限制

• 逻辑通用,跨库改动小

缺点

• 大数据量必慢,全量生成行号开销极大

• 多层嵌套SQL臃肿,可读性差

• 深分页性能断崖下跌

  1. OFFSET FETCH 分页

优点

• SQL极简,代码整洁易维护

• 前几页分页速度快

• 原生语法,优化器原生支持

缺点

• 偏移量越大性能越差

• 百万级数据分页基本不可用

• 并发增删易出现数据错乱

  1. Keyset 键集分页

优点

• 百万/千万级数据分页性能无敌

• 不受页码深浅影响,速度恒定

• 占用资源最少,数据库压力最小

• 分页数据最稳定

缺点

• 不支持直接跳转到指定页码

• 前端需要额外存储上一页末尾锚点值

• 多字段排序条件书写略繁琐

五、业务选型最终建议

  1. 老旧DB2环境(9.7以下)

只能用:ROW_NUMBER 分页

  1. 后台管理系统、数据量小、需要跳页

优先:OFFSET FETCH 分页

  1. APP列表、日志、订单、大数据流、千万级表

强制用:Keyset 键集分页

  1. 混合最优方案

前100页用OFFSET,100页后切换键集分页,兼顾体验与性能

六、DB2分页通用强制规范(三种都要遵守)

  1. 所有分页必须带ORDER BY,否则分页结果随机错乱

  2. 排序字段建立单列/复合索引,无索引所有分页全废

  3. 禁止SELECT *,只查业务所需字段,大幅提速

  4. 大表严禁使用深偏移分页,优先键集分页

相关推荐
倒流时光三十年1 小时前
PostgreSQL 中的 NULL 陷阱:从一次排除过滤说起
java·数据库·postgresql
weixin_444012931 小时前
SQL处理大规模分组聚合的内存限制_调整服务器配置.txt
jvm·数据库·python
接着奏乐接着舞2 小时前
redis 知识点(java)
数据库·mysql
2401_867623982 小时前
SQL如何提取分组中的第一条记录_使用ROW_NUMBER定位数据
jvm·数据库·python
lifewange2 小时前
Hive 数据库 增删改 完整操作指南
数据库·hive·hadoop
Mike117.2 小时前
GBase 8c 写入高峰抖一下,我通常会先看检查点和 WAL
数据库
C137的本贾尼2 小时前
子查询与合并查询:SQL 的高级过滤技巧
数据库·sql
jingyu飞鸟2 小时前
linux系统二进制安装MySQL 8.4、8.0版本数据库,配置crontab和xtrabackup数据库热备份脚本
linux·数据库·mysql
小江的记录本3 小时前
【MySQL】《MySQL日志面试背诵版+思维导图》(核心考点 + MySQL 8.0最新优化)
java·数据库·后端·python·sql·mysql·面试