有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)
答案 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(在最新版本中有一些优化器改进),查询可能会以不同方式重写。
即使在同一版本中,同一查询的最终执行计划(尤其是对于更复杂的查询)也可能因执行而异,具体取决于可用的索引,表的大小以及其他几个因素。