> 参考的优秀文章
优化LIMIT分页--《高性能MySQL》(电子工业出版社)
> 场景描述
遇到一个场景:查询排序后的结果集较大,我们采用分页显示,每页显示20条记录,但是查询效率还是不尽理想。
结果,采用以下两个手段优化效率:
1、对排序的字段加上索引(普通索引,即BTREE),加了索引后,普通查询的效率加快了,但偏移量大的数据(比如排序靠后的数据)查询还是较慢。
2、借鉴《高性能MySQL》的手段,减少扫描范围、延迟关联,偏移量大的数据查询效率也得到优化。
> 简单的实验
版本说明:
-- 5.6.19 select version();
实验条数:
-- 大概171751条记录 select count(1) from t_user t;
没有索引情况下:
-- 无索引下,排序查询TOP20记录,需时约0.502秒 select * from t_user t order by t.`create_time` desc limit 20; -- 无索引下,排序查询第15000+记录,需时约2.485秒 select * from t_user t order by t.`create_time` desc limit 150000, 20;
添加索引后:
-- 添加索引后,排序查询TOP20记录,需时约0.003秒 select * from t_user t order by t.`create_time` desc limit 20; -- 添加索引后,排序查询第15000+记录,需时约1.838秒 select * from t_user t order by t.`create_time` desc limit 150000, 20;
添加索引、减少扫描范围、延迟关联后:
-- 添加索引后,排序查询TOP20记录,需时约0.004秒 select t.* from t_user t inner join ( select t.`id` from t_user t order by t.`create_time` desc limit 20 ) order_result on t.id = order_result.id order by t.`create_time` desc; -- 添加索引后,排序查询第15000+记录,需时约0.491秒 select t.* from t_user t inner join ( select t.`id` from t_user t order by t.`create_time` desc limit 150000, 20 ) order_result on t.id = order_result.id order by t.`create_time` desc;