深分页问题 (Deep Pagination)
🔴 难点描述: 在业务中经常遇到需要分页查看历史数据的需求。当执行 LIMIT 1000000, 10 时,查询速度会变得极慢,甚至导致数据库卡死。
原理: MySQL 在执行 LIMIT offset, N 时,并不是直接跳过 offset 行,而是先读取 offset + N 行数据(在此例中是 1,000,010 行),抛弃掉前面的 offset 行,只取最后 N 行返回。
瓶颈: 这涉及大量的回表操作(如果不是覆盖索引)和无效的数据扫描,造成极大的 I/O 浪费。
解决方案:
延迟关联(Deferred Join): 先通过覆盖索引查出目标 ID,再通过 ID 关联原表。
SQL
-- 优化前
SELECT * FROM users ORDER BY id LIMIT 1000000, 10;
-- 优化后
SELECT a.* FROM users a
INNER JOIN (SELECT id FROM users ORDER BY id LIMIT 1000000, 10) b
ON a.id = b.id;
游标法(Seek Method): 依赖上一页的最后一条 ID,避免使用 OFFSET。
SQL
SELECT * FROM users WHERE id > last_page_max_id ORDER BY id LIMIT 10;


评论