mysql 性能优化之exists 写法不一样,性能提升400倍

业务需求 查询订单中包含商品《高性能 mysql》 的单据总量

上代码

select count(1) from saleorder a 
                          where a.tid = 180571   and exists(select 1 from saleorderdetail e1 where a.tid = e1.tid and a.billid = e1.billid and e1.goodsid in (1061)

执行时间为 16s

 

mysql 版本为 

5.6.16-log

查看执行计划

1PRIMARYarefPRIMARY,bo_billdate,bo_createdate,bo_billno,fk_saleorder_bid,fk_saleorder_cmpid,fk_saleorder_empid,fk_saleorder_storeid,fk_saleorder_useridbo_billdate4const13994Using where; Using index
2DEPENDENT SUBQUERYe1refPRIMARY,fk_saleorderdetail_skuid,fk_saleorderdetail_storeidfk_saleorderdetail_skuid8userdb0001.a.tid,const4

Using where; Using index

 

相同的语句 我再来看 8.0  中执行,只需要0.04S

mysql 版本为 

8.0.18

再 看执行计划 

SIMPLE<subquery2> ALL     100.00Using where
SIMPLEa eq_refPRIMARY,bo_billdate,bo_createdate,bo_billno,fk_saleorder_bid,fk_saleorder_cmpid,fk_saleorder_empid,fk_saleorder_storeid,fk_saleorder_useridPRIMARY12const,<subquery2>.billid1100.00Using index
MATERIALIZEDe1 refPRIMARY,fk_saleorderdetail_skuid,fk_saleorderdetail_storeidfk_saleorderdetail_skuid8const,const2402100.00Using index

 可以看到 8.0对子查询做了优化。

那么在 8.0以前版本中 exists怎么优化呢。

两种方案,1种是改写为 join

      select count(distinct a.tid,a.billid) from saleorder a  inner join saleorderdetail e1 on a.tid = e1.tid and a.billid = e1.billid
                                where a.tid = 180571  and  e1.goodsid in (1061) 

查询时间为0.04S

 

第二种方案,改in

select count(1) from saleorder a 
                                where a.tid = 180571  and (a.tid,a.billid) in (select tid,billid from  saleorderdetail e1 where e1.tid =180571 and  e1.goodsid in (1061))
     同样查询时间也只有 0.04S

 

 

结论 mysql 8.0以前的版本 要注意 exists与in 的子查询 会不会产生DEPENDENT SUBQUERY 如果产生,则必须优化它。

mysql 8.0及以后版本在子查询方面,做了较大优化。可以放心写。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值