2012-07-12 44 views
0

我有三個表查找缺失值,第一個是電子郵件地址列表:MySQL的最有效的方法來從多個表

addresses: 
id - integer, this is the primary key<br> 
email - varchar(255) field holding the address 

sent: 
sid - integer, foreign key references id in addresses table 

received: 
rid - integer, foreign key references id in addresses table 

顯然,「已發送」和「收到」表有其他列,但他們對這個問題並不重要。每發送或接收一封電子郵件都會填寫已發送和已接收的表格,並且如果地址尚未存在於「地址」表格中,則會被添加。表格可能會變得很大(100,000+)。

定期清除「已發送」和「已接收」表的條目,並因各種原因刪除條目,在「地址」表中留下孤立條目。

我正在尋找最有效的方法在MySQL中清除「地址」表中的孤立條目。查詢我至今是:

delete 
from addresses 
where id not in 
     (select rid from received) 
    and id not in 
     (select sid from sent); 

這工作,但它可以採取looong時間運行,絕對不是這樣做的最有效的方法!我也試過這樣:

delete 
from addresses 
where not exists 
     (select 'x' from sent where sent.sid=addresses.id) 
    and not exists 
     (select 'x' from rceieved where recieved.rid=addresses.id); 

這是一個有點快,但仍需要很長的時間,我懷疑我需要使用JOIN語法,但我的SQL知識已經用完了我在這一點!

+1

表中有哪些索引可用?它可能是沒有被使用。 – 2012-07-12 09:57:40

+0

爲3個表的查詢和'SHOW CREATE TABLE'輸出提供'EXPLAIN'。 – 2012-07-12 10:03:34

+0

嘗試我的查詢一次,我已經刪除了在條款和加入QUERIES – 2012-07-12 10:22:04

回答

1

這應該做的伎倆

​​
+0

是的,當然沒有 - 更快,謝謝 – Chris 2012-07-12 14:25:47

0

試試這個: 從不會忽略刪除LEFT JOIN發送小號 上(a.sentid = s.id),其中s.id爲空

0

我對不起,我不能給出明確的答案。但我也有類似的問題,並環顧四周之後,似乎只有兩種主要的選擇:

  1. 使用WHERE x NOT IN y
  2. 使用LEFT JOIN x ON y WHERE z IS NULL

我嘗試這兩種方法,通過比較兩個表的2822291和916626條記錄。

的性能結論如下:

  • 類型1是比類型2(600秒VS 6000秒)
  • Indexes或鍵有此操作對性能的影響合理快顯著在這兩種類型。
  • 性能幾乎與實際的DISTINCT值無關。因此,比較兩個表的2000個不同值或僅15個大致相同的時間。

因此,截至目前(08-2013)的結論似乎是選項1仍然是更快的方法。使用NOT EXISTS可能會更快,但與類型1相比,性能變化並不顯着。

我希望這能最終幫助任何人。

0

做了一些測試,使用2個300k myisam表,其中包含2個id列(和其他幾個不同的列)。除了一張表中的2條記錄以外,ID是相同的。嘗試了3種方法中提到發現這些ID:

WHERE NOT EXISTS

LEFT JOIN

IN()

確保使用SQL_NO_CACHE和所有查詢同樣執行,服務器返回兩個結果約14.6秒。

上述差異必須是緩存,不同版本的mysql和/或一般服務器配置。

相關問題