> 參考的優秀文章
優化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;
