Mysql一条多表关联SQL把CPU打爆了,如何优化

今天是清明假期的第三天,收到同事的求助,DB的CPU被打爆了!

查看监控,CPU已经被打爆100%

登录mysql,DB无锁阻塞,元凶是一个异常sql,存在39个并发执行。

SQL的明细如下:

select TEMPSALE.USER_ID_BUY,       TEMPSALE.ORDER_AMOUNT,       TEMPSALE.LAST_UPDATED_DATEfrom T_EAC_BU_SG_CO_INFO TSIrightjoin  (select TOI.SALE_PRO_ID,          TOI.USER_ID_BUY,          TOI.ORDER_AMOUNT,          TOI.LAST_UPDATED_DATE   from T_EAC_BU_ORDER_INFO TOI   left join T_EAC_BU_SALE_GOOD_INFO TEC on TOI.SALE_PRO_ID = TEC.SALE_PRO_ID) TEMPSALE on TSI.SALE_PRO_ID = TEMPSALE.SALE_PRO_IDwhere TSI.CAR_ORIGIN_CODE= '000000008671c3180186829f41ad336f' ;                                

首先看看该sql的执行计划吧

相关的表结构如下:

分析:

先来看看正常情况下这条sql单次执行耗时为多少

索引有缺失吗?

相关表的索引创建无大碍,关联字段与where谓词字段都已经创建好了索引。

针对这条异常sql,我们还有优化的空间吗??

解读执行计划,扫描 表别名为 TOI的表,全表扫描估算数据量为514049, Extra  列为 NULL 没有任何的谓词过滤无效数据。扫描后的结果与 表别名为 TEC 的表 Using index (SALE_PRO_ID字段)进行关联。再与 表别名为 TSI 的表 Using where 使用谓词过滤后关联。

执行耗时绝大部分耗时都在第一步与第二步,即 from T_EAC_BU_ORDER_INFO TOI   left join T_EAC_BU_SALE_GOOD_INFO TEC on TOI.SALE_PRO_ID = TEC.SALE_PRO_ID ,在不影响语义的前提下,

我们改写sql把能过滤大部分数据的谓词表提前作为驱动表执行,这样就能最大程度提高执行效率,缩短执行时间了。即,我们将原本 T_EAC_BU_ORDER_INFO 与 T_EAC_BU_SALE_GOOD_INFO 无谓词的关联,改写为 T_EAC_BU_ORDER_INFO 与 T_EAC_BU_SG_CO_INFO 带谓词关联。

改写后的sql

未优化前sql与优化后sql执行时间对比

未优化前sql与优化后sql执行计划对比

至此,原本执行耗时由9秒+的问题sql,优化至0.00秒,性能提升杠杠的。

总结:

1、多表关联,表谓词能提前的提前过滤无效数据

2、多表关联,小表驱动大表

3、大部分sql优化为最佳索引缺失,部分sql优化需要改写sql

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值