微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何优化此查询以删除另一个表中没有相应ID的记录?

如何解决如何优化此查询以删除另一个表中没有相应ID的记录?

我有一个500万条记录的“主”表,其中包含一个主键ID(MovieId),其他几个表都将其用作外键(许多表)。

这些多对多表中的某些表具有数百万条记录(最多2000万条)。

我想从主表中不存在外键的多对多表中删除所有记录。这将极大地减少它们的大小(每个记录减少到“仅”一百万或两百万条记录)。

但是执行此操作的sql似乎非常耗时-实质上循环超过2000万条记录,每次循环浏览主表中的多达50万条记录以查看外键是否在2000万条中五十万个主表记录中存在多对多表记录作为主键。

我可以想象这需要很长时间。有(相对)快速方法吗?

我实现此目标的第一个想法是:

DELETE FROM ACTORS_MOVIES_M2M
WHERE MovieiD NOT EXISTS (SELECT MovieiD FROM MOVIES_MAIN)

...再说一遍,我觉得这需要...

解决方法

您要编写的查询:

delete m2m 
from actors_movies_m2m m2m
where not exists (select 1 from movies_main m where m.movieid = m2m.movieid)

movies_main(movieid)上的索引将帮助子查询快速执行(假设movieidmovies_main的主键,它已经存在)。

尽管从技术上讲这是正确的,但这可能不是最有效的方法。如果要删除表格的重要部分,那么清空并重新填充表格可能会更有效。

create table tmp_actors_movies_m2m as
select * 
from actors_movies_m2m m2m
where exists (select 1 from movies_main m where m.movieid = m2m.movieid)

truncate table actors_movies_m2m;  -- back it up first!

insert into actors_movies_m2m 
select * 
from tmp_actors_movies_m2m;

drop table actors_movies_m2m;

请注意,您的问题本身表明存在潜在的设计问题。通过使用on delete cascade选项设置适当的外键,可以从一开始就避免孤立记录:

create table actors_movies_m2m  (
    ... -- columns here
    movieid int references movies_main (movieid) on delete cascade
);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。