mysql 优化器之——in关查询生成的执行计划及优化过程

SQL语句如下,其作用是将指定alarm.svalue15=“Fa88315dce4a64382906f4db70ba5a2fe”所对应的alarm_aux.alarm_rep_count置空,同时这对应的数据很少几条,按理说,是很快就完成更新动作,但实际上评估行数为1819784,时间为12m50.08s

update alarm_aux set alarm_rep_count = null where alarm_id in (select id from alarm where alarm.svalue15 = 'Fa88315dce4a64382906f4db70ba5a2fe');
 

执行计划

mysql 优化器之——in关查询生成的执行计划及优化过程_第1张图片

实际执行

mysql 优化器之——in关查询生成的执行计划及优化过程_第2张图片

慢查询日志输出

核实两张的索引,如下图,可见字段alarm.alarm_id和alarm.svalue15都是有索引的

mysql 优化器之——in关查询生成的执行计划及优化过程_第3张图片

 

通过上述的执行计划和实际执行来看,是用到了in相关子查询,引用NULL,针对于此,优化方法1是去子查询,转为两表关联

如下是优化后SQL的执行计划,可见影响行数为1。

 

mysql 优化器之——in关查询生成的执行计划及优化过程_第4张图片

 

优化后SQL实际执行时间

mysql 优化器之——in关查询生成的执行计划及优化过程_第5张图片

 

总结

1、mysql对于子查询过程是先外部,后内部,若in子查询结果中有NULL返回,则影响外部查询评估,没有充分利用索引

2、尽可能将in相关子查询转换成exists相关子查询

3、去子查询,进而转换两表关联

 

 

 

你可能感兴趣的:(mysql)