mysql5.5中sql中包含id in(子查询) 不走索引,而5.6之后走索引的分析

       问题出现在今天,项目中别人代码中为了代码简洁吧,经常用一条sql就把所有的关联数据取出来了(建议不要用子查询,能分来查就分开差,如果非要用子查询,建议多用索引查)

下面是出现问题的sql截图,一个sql用了71s  ,数据量刚到10W条(出问题的是本地的数据库)

再分析对sql分析之前我将两个查询拆开,发现都是用的0.05s.在此不加截图。在数据量不大的情况下,单表查询基本上都是维持在0.0几s以内的。

然后我分析了下这条sql 

type = All  是全表扫描 ,sql中用了id的主键,竟然没有走索引 。这样的话就相当于查询的数据量为1600*132571  

所以我暂时的解决方法是将子查询改成关联查询或者分开查。这个不重要。重要的是我发现先上的sql的运行时间是0.058s

同样对sql进行分析

咱们一一分析下:

 

首先select_type 从原来的primary,dependent subquery 变成了simple

simple:表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple

primary一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary。

dependent subquery:与dependent union类似,表示这个subquery的查询要受到外部表查询的影响

 

然后是type 从两个ALL   一个变成了eq_ref

eq_ref:在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用

possible_keys、key、key_len 从刚才什么都没有, 现在有了一个

rows 行数由于当前使用索引页变为了1 所以现在的数据量是131984

 

分析之后重点来了,找原因

我将本地所有数据备份到了线上的临时库里,发现查询的时间也是0.05左右。由于两个数据库配置都是默认的,所以我不信是出自配置上的。因此我去看了看mysql的版本,我本地的是安装程序安装的5.5版本而线上是用的5.6版本

5.6对子查询做了很大的优化,此处不加阐述 ,自己百度吧。

 

由上面来开5.5是将两个表都取出然后一一比对,这样耗时太大。

5.6之后就有了将子查询的结果返回到主查询的条件中进行查询。感觉这才是真正是用子查询自己想的逻辑吧。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值