慢sql优化

这篇笔记主要记录:大表深分页问题解决:

问题描述

A表中,数据量大约在250W左右,并且还在持续增长
表中的核心字段:
id:
店铺id:
用户id:
模板id:

我现在的场景是,在某一个店铺关闭的时候,需要把这个表中对应店铺下所有的用户数据都删除,因为考虑到数据量较大,所以采用异步方式来处理

异步线程在处理的时候,也是分批处理的,不可能一次全部删除完毕,所以,提供了两个接口:
1.切割接口:一次切割1000条数据,然后返回
2.执行接口:根据切割接口返回的数据,执行删除操作
对于这两个接口,可以认为:在异步消息消费到之后,会先调用split接口,切分一部分数据,然后获取到切分之后的结果之后,再调用执行接口

这两个接口有可能是并行执行的,所以需要考虑防止对数据出现重复处理的问题

切割接口里面,原来使用的sql是:select id,店铺id,用户id,模板id from A where 店铺id = ‘’ limit 0,1000;
这样有一个问题:如果这个店铺的数据量过大的时候,会出现:select id,店铺id,用户id,模板id from A where 店铺id = ‘’ limit 150000,1000;
这样的话,sql会慢,慢就导致dubbo接口会超时
看了下执行计划,也走了索引,并且也使用了索引覆盖,但是因为扫描的行数比较大,大约扫描了50W行记录,执行耗时大约300ms左右;

在预发环境验证了下,如果一个店铺下有30W的用户,在删除时,超过15W的时候,sql就会执行较慢,进而会导致部分dubbo接口请求超时

解决方案:

针对这个sql,需要进行优化,优化的方案:
sql调整为:select id,店铺id,用户id from A where 店铺id = ‘’ and id > X limit 1000;
这里的X为每次切割之后,1000条记录中的最后一条记录的主键id,这样,就会好很多,基本上每次执行耗时12ms左右

所以,及时在遍历到第15W条记录的时候,sql就会变成:select id,店铺id,用户id from A where 店铺id = ‘’ and id > 150000 limit 1000;
这样的执行效率,要远高于最开始的limit start,pageSize这种方式,最新的这种方式,执行耗时大约在15ms左右,比原来提升了20倍左右

深分页优化思路

1.如果主键是递增的,可以考虑每次分页之后,记录最后一个主键id,然后下次分页的时候,使用select * from table where id > 1000 limit 10
2.可以考虑使用覆盖索引,尽量不查询不使用的数据
3.可以考虑使用关联查询 select * from table where id > (select id from table where 条件 limit 1000,1) limit 10;
4.select * from table t1 inner join (select id from table where 条件 limit 1000,10) t2 on t1.id = t2.id;

我认为,效率最高的还是第一种,当然 这个也是case by case,不同的场景下,可能效果是不一样的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值