File tree Expand file tree Collapse file tree 3 files changed +748
-11
lines changed
Expand file tree Collapse file tree 3 files changed +748
-11
lines changed Original file line number Diff line number Diff line change @@ -127,12 +127,27 @@ LIMIT 1000000, 10;
127127
128128## 总结
129129
130- 本文总结了几种常见的深度分页优化方案:
130+ 深度分页问题的根本原因在于:当 ` LIMIT ` 的偏移量过大时,MySQL 需要扫描并跳过大量记录才能获取目标数据,查询优化器可能放弃索引而选择全表扫描。此时即使有索引,也无法避免大量的回表操作,导致查询性能急剧下降。
131131
132- 1 . ** 范围查询** : 基于 ID 连续性进行分页,通过记录上一页最后一条记录的 ID 来获取下一页数据。适合 ID 连续且按 ID 查询的场景,但在 ID 不连续或需要按其他字段排序时存在局限。
133- 2 . ** 子查询** : 先通过子查询获取分页的起始主键值,再根据主键进行筛选分页。利用主键索引提高效率,但子查询会生成临时表,复杂场景下性能不佳。
134- 3 . ** 延迟关联 (INNER JOIN)** : 使用 ` INNER JOIN ` 将分页操作转移到主键索引上,减少回表次数。相比子查询,延迟关联的性能更优,适合大数据量的分页查询。
135- 4 . ** 覆盖索引** : 通过索引直接获取所需字段,避免回表操作,减少 IO 开销,适合查询特定字段的场景。但当结果集较大时,MySQL 可能会选择全表扫描。
132+ 本文介绍了四种常见的深度分页优化方案,各方案的特点及适用场景对比如下:
133+
134+ | 优化方案 | 核心思路 | 适用场景 | 限制 |
135+ | ------------ | ------------------------------------------------------------------- | ----------------------------------- | ------------------------------------------------ |
136+ | ** 范围查询** | 记录上一页最后一条 ID,通过 ` WHERE id > last_id LIMIT n ` 获取下一页 | ID 连续、按 ID 排序、允许游标式翻页 | 不支持跳页、ID 不连续时失效、非 ID 排序不适用 |
137+ | ** 子查询** | 先通过子查询获取起始主键,再根据主键过滤 | 需要支持传统 OFFSET 翻页 | 子查询可能产生临时表、仅适用于 ID 正序 |
138+ | ** 延迟关联** | 用 ` INNER JOIN ` 将分页转移到主键索引,减少回表 | 大数据量分页、需要传统翻页逻辑 | SQL 相对复杂 |
139+ | ** 覆盖索引** | 建立包含查询字段的联合索引,避免回表 | 查询字段固定、可建立合适索引 | 字段较多时索引维护成本高、大结果集可能走全表扫描 |
140+
141+ ** 方案选择建议** :
142+
143+ - ** 优先使用延迟关联** :对于大多数需要支持传统 ` LIMIT offset, size ` 翻页逻辑的场景,延迟关联是性能和可维护性较好的选择。
144+ - ** 考虑范围查询(游标分页)** :如果业务允许使用"下一页"式的游标翻页(如社交媒体 feed 流、无限滚动),范围查询性能最佳且稳定。
145+ - ** 覆盖索引作为补充** :当查询字段固定且数量不多时,可配合其他方案建立覆盖索引进一步优化。
146+
147+ ** 注意事项** :
148+
149+ - 无论采用哪种方案,都应注意监控实际执行计划(` EXPLAIN ` ),确保优化器按预期使用索引。
150+ - 对于超深分页(如百万级偏移量),应从业务层面评估是否真的需要支持,考虑限制最大翻页数或采用其他检索方式(如搜索引擎)。
136151
137152## 参考
138153
You can’t perform that action at this time.
0 commit comments