-1

有 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)

解释输出:

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)

4

1 回答 1

1

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

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

这种类型的查询称为antijoin(或 anti-semijoin),也可以用另一种方式编写,使用 a 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(在最近的版本中有一些优化器改进),查询可能会以不同的方式重写。

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

于 2012-10-31T20:37:50.727 回答