![](/img/trans.png)
[英]Most efficient way to select multiple rows from multiple tables with a list of IDs using 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
對不起,我不能真正給出確切的答案。 但是我有一個類似的問題,環顧四周之后,似乎只有兩個主要選擇:
WHERE x NOT IN y
LEFT JOIN x ON y WHERE z IS NULL
我通過比較分別為2822291和916626記錄的兩個表來嘗試了這兩種方法。
性能結論如下:
因此,總結一下,截至目前(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.