问题现象:采用子查询的DELETE执行得非常慢,改写成SELECT后执行却很快,最后把这个子查询DELETE改写成JOIN优化过程
1.问题描述:
采用子查询的DELETE执行语句,执行效率非常慢;但把DELETE换成SELECT后,执行秒出结果,这是何故?遂查看执行计划:
可以看下执行计划,看下type类型:ALL应该是全表扫描,rows为几千万的话,所以执行效率很慢
改成SELECT后,执行计划如下变为:type=ref 基于主键的等值查询,rows为几百条,所以节省很多效率;
2.优化思路:
既然这个SQL把DELETE改成SELECT后执行效率就可以获得很大提升,除此外没特别区别,可能是查询优化器方面有些不足,导致无法直接优化,就得另想办法了。我们的思路是把基于子查询的DELETE简化改写成多表JOIN后DELETE(一般来说,子查询效率比较低的话,可以考虑改写成JOIN),多表DELETE的语法课参考:https://dev.mysql.com/doc/refman/5.7/en/delete.html#idm140469624466800,例如这样的:
DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL