2012-10-31 259 views
-1

有DDL语句:MySQL的:相关子查询选择类型关联子查询

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

哦,对不起。我更新了问题。 – VMN

回答

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的(即在最近的版本进行了一些优化改进),查询可被不同改写。

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

+0

优化器重写后如何查看查询? – VMN

+0

不确定以前的版本。对于5.6,请查看本文:[优化器跟踪:如何配置它](http://guilhembichot.blogspot.gr/2011/09/optimizer-tracing-how-to-configure-it.html) –

+0

谢谢。 是否可以禁用给定查询的优化? – VMN