栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

慢sql优化

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

慢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,不同的场景下,可能效果是不一样的

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/929944.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号