执行的SQL如下:
EXPLAIN DELETE FROM t_app_user WHERE userId IN
(SELECT inviteeId FROM t_partner_invite WHERE inviterId="76af4c4e3f7b40618ec9290b63dac9f0");
执行结果

Extra列对应值得含义
- Using where:表示优化器需要通过索引回表查询数据。
- Using index:即覆盖索引,表示直接访问索引就足够获取到所需要的数据,不需要通过索引回表,通常是通过将待查询字段建立联合索引实现。
- Using filesort:文件排序,这个一般在ORDER BY时候,数据量过大,MySQL会将所有数据召回内存中排序,比较消耗资源。
从explain结果可以发现:先全表扫描 t_app_user,然后逐行执行子查询判断条件是否满足;显然,这个执行计划和我们预期不符合,因为并没有走索引。
但是如果换成把delete换成select,就会走索引。如下:
EXPLAIN SELECT * FROM t_app_user WHERE userId IN (SELECT inviteeId FROM t_partner_invite WHERE inviterId="76af4c4e3f7b40618ec9290b63dac9f0");

为什么select in子查询会走索引,delete in子查询却不会走索引呢?
原因分析
实际执行的时候,MySQL对select in子查询做了优化
,把子查询改成join的方式,
所以可以走索引。但是很遗憾,对于delete in子查询,MySQL却没有对它做这个优化。
优化
使用inner join
EXPLAIN DELETE t1 FROM t_app_user t1 INNER JOIN t_partner_invite t2 ON t1.userId= t2.inviterId

其实呢,给表加别名,也可以解决这个问题哦,如下:
EXPLAIN DELETE a FROM t_app_user a WHERE userId IN (SELECT inviteeId FROM t_partner_invite WHERE inviterId="76af4c4e3f7b40618ec9290b63dac9f0");
SHOW WARNINGS;
