Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何优化此查询以删除另一个表中没有相应Id的记录?_Sql_Sql Server_Foreign Keys_Query Optimization_Sql Delete - Fatal编程技术网

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

Sql 如何优化此查询以删除另一个表中没有相应Id的记录?,sql,sql-server,foreign-keys,query-optimization,sql-delete,Sql,Sql Server,Foreign Keys,Query Optimization,Sql Delete,我有一个50万条记录的“主”表,其中包含一个主键Id(MovieId),其他几个表将其用作外键(多对多表) 其中一些多对多表有数百万条记录(多达2000万条) 我想删除主表中不存在外键的多对多表中的所有记录。这将极大地减少它们的大小(每个记录“仅”减少到100万或200万条) 但是完成这项工作的SQL似乎非常耗时——基本上是循环超过2000万条记录,每次查看主表中多达50万条记录,查看2000万多对多表记录中的外键是否作为主键存在于50万条主表记录中 我可以想象这需要很长时间。有没有(相对)快速

我有一个50万条记录的“主”表,其中包含一个主键Id(MovieId),其他几个表将其用作外键(多对多表)

其中一些多对多表有数百万条记录(多达2000万条)

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

但是完成这项工作的SQL似乎非常耗时——基本上是循环超过2000万条记录,每次查看主表中多达50万条记录,查看2000万多对多表记录中的外键是否作为主键存在于50万条主表记录中

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

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

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\u main(movieid)
上的索引将有助于快速执行子查询(假设
movieid
movies\u 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;
请注意,您的问题本身表明存在潜在的设计问题。通过使用删除级联上的
选项设置适当的外键,可以从一开始就避免孤立记录:

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

该代码不进行解析。在事实之后(填充表之后)添加索引是否有任何效果,或者仅在添加记录时才起作用。在添加索引时,是否会对已经存在的记录进行索引?