mysql使用limit分页优化方案
2020-06-08 本文已影响0人
就叫basi
准备数据是20000000条数据
![](https://img.haomeiwen.com/i15503876/4a0fa84ad42f3154.png)
在分页场景下,使用limit start end,我们分别看下从10000, 100000, 1000000开始分页的执行时间(每页取10条),如下图
![](https://img.haomeiwen.com/i15503876/603f2aa0f2af5b15.png)
![](https://img.haomeiwen.com/i15503876/3b2895911fbfab44.png)
![](https://img.haomeiwen.com/i15503876/6281163d94df8e1a.png)
当start较小时,查询没有性能问题,但是如上图查询时间所示,随着start增大,查询消耗时间也在递增,在start=10000000时,分页竟然消耗了2秒多,这是不能忍受的。
![](https://img.haomeiwen.com/i15503876/992a907722fa844f.png)
由此引出对limit分页的优化,首先来explain该语句,看到查询没有使用到任何的索引,进行的是全表扫描,假如limit分页用到了索引是不是会快很多呢!
![](https://img.haomeiwen.com/i15503876/e3e060d350f00177.png)
优化1
![](https://img.haomeiwen.com/i15503876/1d69a7229c257e8a.png)
下面来分析一下这条sql!如下图所示,where下面的括号中的SUBQUERY查询使用到了主键索引,主查询使用到了索引的范围查询,所以速度会快很多
![](https://img.haomeiwen.com/i15503876/8e707b2f9d62f25f.png)
优化2
![](https://img.haomeiwen.com/i15503876/922be946b412e7b3.png)
explain分析一下,第一行是select * from user_innodb形成的临时表使用的是全表扫描,第二行是 (SELECT id FROM user_innodb LIMIT 10000000, 10)形成的,使用的是eq_ref,第三行是全表扫描a和bjoin形成的派生表,使用到的是index,所以速度也会快很多
![](https://img.haomeiwen.com/i15503876/3925f65278db4144.png)
![](https://img.haomeiwen.com/i15503876/6710aabf179c5620.png)