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');
执行计划
实际执行
慢查询日志输出
核实两张的索引,如下图,可见字段alarm.alarm_id和alarm.svalue15都是有索引的
通过上述的执行计划和实际执行来看,是用到了in相关子查询,引用NULL,针对于此,优化方法1是去子查询,转为两表关联
如下是优化后SQL的执行计划,可见影响行数为1。
优化后SQL实际执行时间
总结
1、mysql对于子查询过程是先外部,后内部,若in子查询结果中有NULL返回,则影响外部查询评估,没有充分利用索引
2、尽可能将in相关子查询转换成exists相关子查询
3、去子查询,进而转换两表关联