告别慢 SQL:MySQL 百万级数据深分页优化策略
·
告别慢 SQL:MySQL 百万级数据深分页优化策略
在后台管理系统中,“分页查询”是标配。但当数据量达到百万级时,你是否遇到过 LIMIT 1000000, 10 查不出来或者执行需要几秒钟的情况?
这就是经典的 Deep Pagination(深分页) 问题。
1. 为什么深分页这么慢?
看下面这条 SQL:
SELECT * FROM t_order ORDER BY id LIMIT 1000000, 10;
你以为 MySQL 是跳过前 100万条,直接取 10 条?
错!
MySQL 的执行逻辑是:
- 扫描满足条件的 1000010 行数据。
- 抛弃前面的 1000000 行。
- 返回最后的 10 行。
这不仅浪费了大量的 IO,如果是 SELECT *,还会因为回表(Back to Table)导致性能进一步恶化。
2. 解决方案 A:延迟关联(覆盖索引优化)
利用覆盖索引先查出主键 ID,再跟原表做 JOIN。因为查 ID 只需要扫描索引树,速度极快。
优化后 SQL:
SELECT t1.*
FROM t_order t1
INNER JOIN (
-- 这里只查 ID,利用覆盖索引,不回表
SELECT id FROM t_order ORDER BY id LIMIT 1000000, 10
) t2 ON t1.id = t2.id;
效果:通常能将几秒的查询优化到几百毫秒。
3. 解决方案 B:游标法(Seek Method)
如果你能拿到上一页最后一条数据的 ID(last_id),并且 ID 是连续或单调递增的,可以直接用 WHERE 过滤。
优化后 SQL:
-- 假设上一页最后一条 ID 是 1000000
SELECT * FROM t_order
WHERE id > 1000000
ORDER BY id ASC
LIMIT 10;
效果:无论翻到第几页,性能都是 O(1) 的,毫秒级响应。
缺点:只能点“下一页”,不能直接跳转到第 N 页(但在移动端 Feeds 流场景非常适用)。
总结
- 普通分页(前几页):直接
LIMIT。 - 管理后台深分页(跳页):用延迟关联。
- App 瀑布流(无限滚动):用游标法 (
WHERE id > ?)。
更多推荐

所有评论(0)