一,问题的引出
在我们做分页查询的时候,一般都是用到这个limit这个关键字。
主要是limit a,b ,从a开始,返回后面的b条数据,会扫描a+b行。当a很大的时候就会影响查询速度。例如,limit10000,20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行。
二,问题的解决方法
我这里整理了一下网上各种地方的解决方法,如果有需要的可以参考参考。
需要优化的例子: select * from user limit 10000,10;
2.1 使用where id>offset 来替代 偏移量
优化后 select * from user where id > 10000 limit 10
优点:使用了主键索引,加快了查询速度
缺点:主键必须是连续的id
类似这种优化的:使用子查询定位id的位置
优化后 select * from user where id >= (select * from user order by id limit 10000,1) limit 10
2.2 join表的方式
优化后 select * from user as a join (select id from user limit 10000,1) as b on a.iid = b.id
这个方法和上边的使用where然后用子查询方法定位查询的记录类似,涉及到了回表和覆盖索引的问题。
回表:从非族簇索引查询数据的时候,因为数据的叶子节点并不是数据行,而且id,还需要这个拿这个id到表里找到具体对应的数据(当然,这个族簇索引是针对InnoDB引擎来说的)
覆盖索引:所谓的覆盖索引就是从非主聚簇索引中就能查到的想要数据,而不需要通过回表从主键索引中查询其他列,能够显著提升性能。
分析优化的sql:这个连接表,其实就是使用了覆盖索引,快速定位到要查询的id(因为id不需要回表,所以查询速度很快)