MySQL:依赖子查询选择不相关子查询的类型

时间:2012-10-31 19:12:10

标签: mysql sql correlated-subquery

有DDL声明:

CREATE TABLE t1(
c1 INT NOT NULL
);
CREATE TABLE t2(
c2 INT NOT NULL
);

我的查询:

SELECT c1 FROM t1 WHERE c1 NOT IN (SELECT c2 from t2)

EXPLAIN输出:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY t1  ALL NULL    NULL    NULL    NULL    3   Using where
2   DEPENDENT SUBQUERY  t2  ALL NULL    NULL    NULL    NULL    3   Using where

子查询与外部查询无关。为什么它的类型是相关的子信息?

UPD:查询为SELECT c1 FROM t1 WHERE c1 NOT IN (SELECT c2 from t2)

1 个答案:

答案 0 :(得分:1)

您正在使用的MySQL版本的执行计划程序/优化程序,在内部将查询重写为相关子查询(或者更准确,这两者都转换为相同的执行计划):

SELECT c1 
FROM t1 
WHERE NOT EXISTS 
      (SELECT * from t2 WHERE c2 = t1.c1) ;

这种类型的查询称为 antijoin (或反半连接),也可以用另一种方式编写,LEFT JOIN / WHERE IS NULL,在MySQL中生成(5.1)和5.5版本)略有不同的解释计划:

SELECT t1.c1 
FROM t1 
  LEFT JOIN t2 ON t2.c2 = t1.c1
WHERE t2.c2 IS NULL ;

请注意,在其他版本中,如5.6(仍在开发中)或MariaDB(在最新版本中有一些优化器改进),查询可能会以不同方式重写。

即使在同一版本中,同一查询的最终执行计划(尤其是对于更复杂的查询)也可能因执行而异,具体取决于可用的索引,表的大小以及其他几个因素。