0

我有三个表,第一个是电子邮件地址列表:

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+)。

“sent”和“received”表的条目会定期清除,并且出于各种原因删除条目,在“addresses”表中留下孤立的条目。

我正在寻找 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 知识已经用完了!

4

4 回答 4

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
于 2012-07-12T10:21:28.257 回答
0

Try this: delete from adresses a left join sent s on (a.sentid=s.id) where s.id is null

于 2012-07-12T10:17:53.933 回答
0

对不起,我真的不能给出肯定的答案。但是我遇到了类似的问题,环顾四周后似乎只有两个主要选择:

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

我通过比较两个表(分别为 2822291 和 916626 条记录)尝试了这两种方法。

性能结论如下:

  • 类型 1明显快于类型 2。(600 秒对 6000 秒)
  • 索引或键对这两种类型的此操作的性能都有合理的影响。
  • 性能几乎与实际 DISTINCT 值的数量无关。因此,比较两个表的 2000 个不同的值或仅 15 个需要大约相同的时间。

因此,结论是,截至目前(08-2013),选项 1 似乎仍然是更快的方法。使用NOT EXISTS可能会更快,但与类型 1 相比,性能变化并不显着。

我希望这最终能帮助任何人。

于 2013-08-21T09:11:41.347 回答
0

使用包含 2 个 id 列(以及其他几个不同的列)的 2 300k myisam 表进行了一些测试。除了一张表中有 2 条记录外,ID 相同。尝试了提到的 3 种方法来查找这些 id:

不存在的地方

左连接

在 ()

确保使用 SQL_NO_CACHE 并且所有查询执行相同,服务器在约 14.6 秒内返回了两个结果。

上面提到的差异必须是缓存、不同版本的 mysql 和/或通用服务器配置。

于 2016-08-18T15:47:15.390 回答