2012-10-31 270 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