在分页场景下,使用limit start end,我们分别看下从10000, 100000, 1000000开始分页的执行时间(每页取10条),如下图
当start较小时,查询没有性能问题,但是如上图查询时间所示,随着start增大,查询消耗时间也在递增,在start=10000000时,分页竟然消耗了2秒多,这是不能忍受的。
由此引出对limit分页的优化,首先来explain该语句,看到查询没有使用到任何的索引,进行的是全表扫描,假如limit分页用到了索引是不是会快很多呢!
explain分析一下,第一行是select * from user_innodb形成的临时表使用的是全表扫描,第二行是 (SELECT id FROM user_innodb LIMIT 10000000, 10)形成的,使用的是eq_ref,第三行是全表扫描a和bjoin形成的派生表,使用到的是index,所以速度也会快很多
SELECT * FROM table LIMIT [offset,] rowsoffset :偏移,从 offset 条之后开始选择数据,如果 offset 不填,则 offset 为0。
rows :从偏移后开始,选择 rows 条数据。
特点:左开右闭,即选取 (offset,offset+rows] 的数据。
SELECT * FROM table LIMIT 5
SELECT * FROM table LIMIT 0,5
区间:(0,5]
offset=0
rows=5-0=5
SELECT * FROM table LIMIT 2,4
区间:(1,5]
offset=1
rows=5-1=4
SELECT * FROM table LIMIT n,m
区间:(n-1,m]
offset=n-1
rows=m-n+1
1、首先我们建立一个表表的数据,这个表里有25条数据,id从1到25。(下图是部分截图)
2、要分页数据,首先我们假设一页有10条数据,我们可以用mysql的limit关键字来限定返回多少条数据。并且用orderby来排序数据,这里用id来排序。所以第一页的sql可以如图这样写。
3、执行后得到的数据如图,就是id从1到10的前10条数据,因为我们是按id升序来排序的。
4、上面第一页的sql是简化的写法,完整的写法如图,得到的结果和上图的一模一样。代码里limit0,10的意思是从第一条数据开始,取10条数据。(注意的是第一条数据是从0开始的)
5、那么第二页的数据,关键是要知道是从哪一条数据开始,可以用这个公式得到:(页码-1) *每页显示多少条,即(2-1)*10=10,所以sql语句如图,limit10,10。
6、执行后,结果正确,得到id从11到20的10条数据。
7、同理第三页数据的sql如图,<br/>就是limit20,10。
8、查询的结果如图,因为这页只剩下5条数据了,所以只显示5条数据。如果你有更多页的数据,后面的数据只需要按上面的公式,得到从哪行开始,就可以写对应的sql语句了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)