2008-12-09 38 views
50

我有2個表(A和B)具有相同的主鍵。我要選擇所有的行有能力的,而不是在B.以下工作:Mysql select不在表中

select * from A where not exists (select * from B where A.pk=B.pk); 

但它似乎(在一個只有10萬行和B中3-10k少〜2秒)

相當糟糕

有沒有更好的方法來運行它?也許作爲一個左連接?

select * from A left join B on A.x=B.y where B.y is null; 

在我的數據上,這似乎運行稍快(〜10%),但一般呢?

+0

你的意思是你在表A中有100k行,在表B中有100k行嗎?或者每個表格只有大約300行,這意味着100,000行掃描(或者希望是索引掃描)。 – ChrisInEdmonton 2008-12-09 20:00:44

回答

35

我在你的第二個例子的格式中使用查詢。連接通常比關聯的子查詢更具可伸縮性。

50

我認爲你最後的聲明是最好的方法。你也可以試試

SELECT A.*  
from A left join B on 
    A.x = B.y 
    where B.y is null 
+1

這沒有任何意義。當B.y爲空時,A.x = B.y永遠不會爲真。你會得到A的所有行,而不僅僅是B中沒有匹配行的那些行。 – 2008-12-09 20:46:43

+2

@Bill,但它的工作原理!此外,它與上面列出的第二條陳述完全相同。 – 2008-12-11 14:12:31

2

我還使用「where table2.id is null」類型條件的左連接。

當然似乎比嵌套查詢選項更有效。

2

聯接通常更快(在MySQL中),但是如果發現它仍然在緩慢移動,您還應該考慮索引方案。通常,作爲外鍵的任何字段設置(使用INNODB)都將具有索引集。如果您使用的是MYISAM,請確保ON語句中的任何列都已編入索引,並且還要考慮將WHERE子句中的所有列添加到索引末尾,以使其成爲覆蓋索引。這使得引擎可以訪問索引中所需的所有數據,無需再次返回原始數據。請記住,這會影響插入/更新/刪除的速度,但可以顯着提高查詢的速度。

-2

這對我有很大的幫助。 Joins總是比子查詢更快地給出結果:

SELECT tbl1.id FROM tbl1 t1 
LEFT OUTER JOIN tbl2 t2 ON t1.id = t2.id 
WHERE t1.id>=100 AND t2.id IS NULL ;