我有三个表,第一个是电子邮件地址列表:
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知识已经用完了!
答案 0 :(得分:1)
这应该可以解决问题
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
答案 1 :(得分:0)
试试这个: 从地址中删除左连接发送的s on(a.sentid = s.id)其中s.id为空
答案 2 :(得分:0)
对不起,我真的无法给出明确的答案。但我遇到了类似的问题,在环顾四周之后,似乎只有两个主要选择:
WHERE x NOT IN y
LEFT JOIN x ON y WHERE z IS NULL
我通过分别比较2822291和916626记录的两个表来尝试这两种方法。
表现结论如下:
因此,截至目前(08-2013),似乎选项1仍然是更快的方式。使用NOT EXISTS
可能会更快,但与类型1相比,性能变化并不显着。
我希望这最终可以帮助任何人。
答案 3 :(得分:0)
使用2个300k myisam表进行了一些测试,其中包含2个id列(以及其他几个不相同的列)。除了一个表中的2个记录外,ID是相同的。尝试了提到的3种方法来找到这些ID:
不存在
LEFT JOIN
IN()
确保使用SQL_NO_CACHE并执行相同的所有查询,服务器在~14.6秒内返回两个结果。
上述差异必须是缓存,不同版本的mysql和/或一般服务器配置。