优化慢查询(替换子查询、增加索引字段)

背景

昨天老大给我分了个活,在日志文件中发现,某条SQL执行耗时14秒左右,我接受到的任务就是优化之,在这里记录一下

原始SQL
select  rel.COMPANY_ID as companyId,account.appid,account.mobile, account.customer_id as customerId  
from tb_account account 
left join tb_account_bank_rela rel on  account.customer_id = rel.customer_id 
where account.status = '1' 
and (select count(1) from tb_union_merchant_product product where product.company_id= account.COMPANY_ID)>=20 
and DATE_FORMAT(account.create_date, '%Y-%m-%d') = date_sub(curdate(), interval 3 day);

在这里插入图片描述
查了一下代码逻辑,主要是筛选满足条件的客户信息,筛选条件为:状态正常且归属公司下必须要有20以上个商品,且三天前注册的客户信息。

优化策略
  • 优化子查询
    原sql在where语句中使用了子查询,这肯定是个优化点,于是我把其中的这个子查询去除之后,重新执行了sql
    在这里插入图片描述
    可见,我们的优化重点确实在该子查询上面。我们可以使用连接语句替换掉子查询语句
  • 索引
    除此之外,最好是在where语句中的条件都是索引字段,这样可以增加查询速度;where后面有三个条件,单表字段为account.status、create_date,可以将他们这两个字段设为索引字段
优化后SQL
select  rel.COMPANY_ID as companyId,account.appid,account.mobile, account.customer_id as customerId  
from tb_account account        
left join tb_account_bank_rela rel on  account.customer_id = rel.customer_id
left join (select company_id,count(1) as productNum from tb_union_merchant_product group by company_id) comp on comp.company_id=account.company_id
where account.status = '1'  
and comp.productNum>20
and DATE_FORMAT(account.create_date, '%Y-%m-%d') = date_sub(curdate(), interval 3 day);

跟原始SQL对比,区别最大的where语句中的子查询换成了连接查询,因为需要对数量进行过滤,所以组建了一张临时表作为关联表;除此之外,status字段和creat_date字段可以添加上查询索引,优化后的sql执行时间为:
在这里插入图片描述
优化了接近100倍,当数据量越大时,这种差距就越明显;我找了之前写原始SQL的同事问了,当时做开发时,SQL执行是根本就没那么慢的,原因就在于当时是用的是开发环境,数据较少,但是到了生产环境,这种查询效率很显然就低了不少。

总结

其实,本次优化的点主要是在优化查询语句和索引上面,没有什么高大上的东西;SQL优化是很大的面,策略也有很多,根据不同的场景,策略肯定不一样,尤其是面对海量数据,再小的优化点也会被放的很大。

除此之外,我理解的sql优化的工作,不仅面对的是SQL,更多的应该是面向业务,从业务层面到数据层面来思考,慢SQL如何正确的重构,我们优化的目标就是使新SQL又快又准。

不断总结,不断记录,希望以后会越来越精通。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值