SQL反加入删除优化
SQL Anti-join Delete Optimisation
我在 postgres 数据库中有两个表,posts
和 users
。 posts
有一个引用 users.id
主键列的 user_id
外键。两个表都很大。
我刚刚删除了一组随机用户(约占总用户的 80%),我想删除所有引用已删除用户的帖子,有效地反加入和删除。最有效的方法是什么?
目前我有这个:
DELETE FROM posts l
WHERE NOT EXISTS
(
SELECT NULL
FROM users r
WHERE r.id = l.user_id
)
有没有更有效的方法?
this link 的某人对不存在与不在与左连接为空进行了一些测试。 Postgre 可以判断 non-exists 和 left-join is null 是反连接,因此会相应地进行。所以你的方法应该是最有效的。您可能会重组为 left-join-is-null 方法,但它可能不会给您带来任何好处。
预防可能会更好。外键约束是更好的选择,具有级联删除。您在问题的评论中提到这不是一个选项。在您的特定情况下它不是一个选项,因为通常情况下,它是:
REFERENCES someTable(someCol) ON DELETE CASCADE ON UPDATE CASCADE
如果要删除80%的用户,那么最快的方法大概是:
create table temp_posts as
select p.*
from posts p
where exists (select 1 from users u where u.id = p.user_id);
truncate table posts;
insert into posts
select *
from temp_posts;
批量插入比更新 table 中的大部分行要少得多。当然,您应该仔细测试一下。截断 table 是从中删除所有行的快速方法。
我在 postgres 数据库中有两个表,posts
和 users
。 posts
有一个引用 users.id
主键列的 user_id
外键。两个表都很大。
我刚刚删除了一组随机用户(约占总用户的 80%),我想删除所有引用已删除用户的帖子,有效地反加入和删除。最有效的方法是什么?
目前我有这个:
DELETE FROM posts l
WHERE NOT EXISTS
(
SELECT NULL
FROM users r
WHERE r.id = l.user_id
)
有没有更有效的方法?
this link 的某人对不存在与不在与左连接为空进行了一些测试。 Postgre 可以判断 non-exists 和 left-join is null 是反连接,因此会相应地进行。所以你的方法应该是最有效的。您可能会重组为 left-join-is-null 方法,但它可能不会给您带来任何好处。
预防可能会更好。外键约束是更好的选择,具有级联删除。您在问题的评论中提到这不是一个选项。在您的特定情况下它不是一个选项,因为通常情况下,它是:
REFERENCES someTable(someCol) ON DELETE CASCADE ON UPDATE CASCADE
如果要删除80%的用户,那么最快的方法大概是:
create table temp_posts as
select p.*
from posts p
where exists (select 1 from users u where u.id = p.user_id);
truncate table posts;
insert into posts
select *
from temp_posts;
批量插入比更新 table 中的大部分行要少得多。当然,您应该仔细测试一下。截断 table 是从中删除所有行的快速方法。