记一次线上sql优化从9s到400ms的过程

    最近线上发版的时候,发现有个接口执行特别慢,前端App的表现就是没有任何的反应,然后从pinpoint上追查接口发现是sql执行特别慢,平均都是在9s左右。这里由于使用了分页查询的 Mybatis interceptor所以同样的sql还需要查询一次count,导致整个耗时在9s左右,单个sql的耗时在5-6秒左右。

    线上有一张订单表数据大概是65万条数据,另一张订单配送任务表数据大概也是65万条数据,有一条sql的 inner join两张表,执行的sql大致如下:

 基于我对join优化的本能(join优化分析博客:Mysql - join(索引和非索引)的实现原理和优化手段也可以参考:https://www.processon.com/view/link/5ff1684ee0b34d19e4f89031),首先想到的就是是否使用了 Index Nested Loop Join,但是一看两个join on的字段都是有索引的。就先看了一下执行计划,如下:

    该执行计划显示一张 65万的数据走了全表扫描,使用了临时表、使用了排序(注意这里写的 filesort可能是内存排序不一定是文件排序)。出于本能我想到了将小表作为驱动表,但是本能也是将两张表的位置进行了交互,但是发现效果没有太大区别。

    我们赶快翻我写的processon上的优化注意点,试着将 inner join换成了 straght_join,就这一个小小的改动整个耗时从 6s变成了 400ms,我一下子就懵了,马上看了一下执行计划,如下:

 两个表的 ALL、ref变成了 eq_ref、ref,并且两个的key都使用了索引,Extra这里没有了临时表,增加了 Usingwherecondition。事后翻盘如果是两个表的数据相差很大这个效果是接受的,但是两个表的数据量都相当,这个性能提升和执行计划还是有点懵的,希望高手帮解惑。

 在列一下从pinpoint上看到的使用 inner joinstraight_join的性能对比:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值