簡體   English   中英

MySQL從多個表中查找缺失值的最有效方法

[英]MySQL most efficient method to find missing values from multiple tables

我有三個表,第一個是電子郵件地址列表:

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

這行得通,但是可能要花很長的時間才能運行,而且絕對不是最有效的方法! 我也試過這個:

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知識已經耗盡了!

這應該可以解決問題

DELETE adresses.* FROM adresses 
LEFT JOIN sent ON sent.sid=adresses.id
LEFT JOIN received ON received.rid=adresses.id
WHERE sent.sid IS NULL AND received.rid IS NULL

嘗試以下操作:從地址中刪除在(a.sentid = s.id)上發送s的左聯接,其中s.id為null

對不起,我不能真正給出確切的答案。 但是我有一個類似的問題,環顧四周之后,似乎只有兩個主要選擇:

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

我通過比較分別為2822291和916626記錄的兩個表來嘗試了這兩種方法。

性能結論如下:

  • 類型1 明顯快於類型2。(600秒vs 6000秒)
  • 索引或鍵對這兩種類型的操作的性能都有合理的影響。
  • 性能幾乎與實際的DISTINCT值數量無關。 因此,比較2000個不同的值或兩個表僅比較15個花費的時間大約相同。

因此,總結一下,截至目前(2013年8月8日),似乎選項1仍然是更快的方法。 使用NOT EXISTS可能會更快,但是與類型1相比,性能變化並不明顯。

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

使用2 300k myisam表進行了一些測試,該表包含2個id列(以及其他幾個不同的列)。 這些ID相同,除了一張表中有2條記錄。 嘗試了上述3種方法來找到這些ID:

不存在

左聯接

IN()

確保使用SQL_NO_CACHE並且所有查詢均執行相同,服務器在大約14.6秒內返回了兩個結果。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM