我有一个名为“downloads”的表,其中包含两个外键列 - “user_id”和“item_id”。我需要从该表中选择所有行,并删除有问题的User或Item不再存在的行。 (查找用户,如果找不到,请删除“下载”中的行,然后查找项目,如果找不到,请删除“下载”中的行。
这是340万行,所以我所有的脚本解决方案都需要6个多小时。我希望有一种更快的,只有SQL的方法来做到这一点?
答案 0 :(得分:26)
使用两个反连接和or
它们在一起:
delete from your_table
where user_id not in (select id from users_table)
or item_id not in (select id from items_table)
完成后,请考虑添加两个外键,每个外键都有一个on delete cascade子句。它会自动为你做这件事。
答案 1 :(得分:3)
delete from your_table where user_id not in (select id from users_table) or item_id not in (select id from items_table)
答案 2 :(得分:0)
认为当行数太多时没有更快的解决方案 在您的服务器上每秒157行
检查用户ID 如果mysql num rows = 0,则删除下载并检查item_id
还有一个关于myswl num rows
性能的类似问题MySQL: Fastest way to count number of rows
编辑:认为最好是创建一些触发器,以便数据库服务器为您完成工作
目前我第一次使用cronjob
答案 3 :(得分:0)
供将来参考。对于这种长期操作。可以独立于SQL优化服务器。例如,如果可以确保sql日志文件位于数据库所在的驱动器的单独磁盘驱动器上,则分离sql服务,对系统磁盘进行碎片整理。 这至少可以减轻这些长时间操作的痛苦。
答案 4 :(得分:0)
我在SQL 2008 R2中发现,如果你的“in”子句包含一个空值(可能来自一个引用该键可以为空的表),则不会返回任何记录!要更正,只需在union部分的选择中添加一个子句:
delete from SomeTable where Key not in (
select SomeTableKey from TableB where SomeTableKey is not null
union
select SomeTableKey from TableC where SomeTableKey is not null
)