mysql大数据量下的limit m , n分页查询缓慢的优化办法

一、日常开发中,有些业务需要,我们使用mysql来实现分页功能的时候,总会用到mysql的limit语法

1.返回符合条件的前10条语句

select * from abc where xxx limit 10;

2.返回符合条件的第11-20条数据

select * from abc where xxx limit 10,20;

也可以说limit n 等价于limit 0,n;

二、实际使用中,在分页的越往后面,加载会变的非常慢

业务中涉及到需要同步查询的表,数量级在千万左右,假如每次查询同步50条记录,越往后查询,分页越大…

select * from abc where xxx limit 1000000,50;
...
select * from abc where xxx limit 9000000,50;

这样的查询非常慢,本地使用navicat模拟时,一般要花费几秒到十几秒不等,sql语句根本不能这样写,因为limit 1000000,50的语法实际上是mysql查找到前1000050条数据,之后丢弃前面的1000000行,这个步骤其实是浪费掉的,服务估计会直接挂掉.

三、优化

1.看到网上有部分使用覆盖索引 ,连接查询优化:

“mysql的查询完全命中索引的时候,称为覆盖索引,是非常快的,因为查询只需要在索引上进行查找,之后可以直接返回,而不用再回数据表拿数据.因此我们可以先查出索引的ID,然后根据Id拿数据.”

select * from abc where id >=   
 (select id from abc where xxx limit 10000, 1) limit 10  

或者

select * from (select id from abc where xxx limit 1000000,50) a left join abc b on a.id = b.id;

这种子查询分页大的时候依然很慢…使用本地navicat,在有大数据量的表中试了一下,也要几秒到十几秒不等(也有可能和电脑性能,网络有关)

select id from abc where xxx limit 1000000,50 -- 3.865s
select id from abc where xxx limit 2000000,100 -- 13.400s
select * from (select id from abc where xxx limit 3000000,50) a left join abc b on a.id = b.id; -- 6.37s

3.可配合业务需要共同优化sql(也是大量数据中分批查询),这种查询最快

 Long startId = 0L;
 List<AbcEntity> abcList = abcService.findListByXxx(startId, xxx);
	for (AbcEntity entity : abcList) {
	 // ......业务逻辑
      startId = entity.getId();
    }

对应的sql语句

select * from abc where xxx and id > #{startId} LIMIT 50;
-- 同上相同数量级的表中测试结果
select * from abc where id > 1000000 LIMIT 50; -- 0.386s
select * from abc where id > 9000000 LIMIT 50;  -- 0.247s
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值