先来看两个SQL
SELECT id,`name`,birthday,email,address FROM `user` LIMIT 1500000,2000;
SELECT id,`name`,birthday,email,address FROM `user` LIMIT 0,2000;
user 表具有二百万条数据,上面两个SQL都是使用limit 关键字对user 表进行简单分页查询,一页2000条数据,截图可以看到第一个SQL比第二个SQL慢了百倍。
sql慢的原因
limit offset,n 语句会先扫描offset+n行数据,然后丢弃前offset行,返回n行数据
也就是说
limit 1500000,2000 扫描了1502000行数据,这个过程需要回表1502000次
而limit 0,2000 只扫描了2000条数据
所以解决深分页问题的思路就是减少回表次数
通过覆盖索引+子查询优化
SELECT id,`name`,birthday,email,address FROM `user` WHERE id>=(SELECT id FROM `user` LIMIT 1500000,1) LIMIT 0,2000;
记录上次的位置优化
假设上一次记录到了1500000,则SQL可以改为
SELECT id,`name`,birthday,email,address FROM `user` WHERE id>=15000000 order by id LIMIT 0,2000;
这个方法是最快的,性能也是最稳定的,
但是要求id是类似于自增的,最好是连续的
如果不是连续的则需要先根据id进行排序以确定第一个ID的值
使用between…and…
如果可以计算出边界值,也可以使用between...and... 关键字,这个方法同样要求id自增且连续
SELECT id,`name`,birthday,email,address FROM `user` WHERE id BETWEEN 1500001 AND 1502000
|