MySQL 分页越查越慢原因

Alexer 发布于 阅读:15 速查

慢的根源不是数据变多,是 LIMIT offset, n 里的 offset 太大。MySQL 必须先按顺序扫过前 offset 行、再整行丢掉,只留下最后 n 行;如果走二级索引,还要一行行回表取整行数据;排序字段没索引时再加一次 filesort。翻得越深,白干的活越多。

-- 翻到第 10001 页:前 10 万行扫完就扔,越翻越慢
SELECT * FROM article ORDER BY id LIMIT 100000, 20;

做法一,记住上一页最后一条的 id,用条件接着往下取,不再数 offset:

SELECT * FROM article WHERE id > 100000 ORDER BY id LIMIT 20;

做法二,必须按非唯一字段排序时,先用覆盖索引只查主键,再拿主键回表取数据,也就是延迟关联:

-- 子查询只在 (create_time, id) 索引上走,不回表
SELECT a.* FROM article a
JOIN (SELECT id FROM article ORDER BY create_time LIMIT 100000, 20) t USING(id);

顺带记一句:排序字段和查询字段都塞进同一个索引里,回表次数就下来了。

语法基础 MySQL 数据库基础