我在postgres数据库中有两个表,posts
和users
。 posts
有一个user_id
外键,它引用了users.id
主键列。两个表都很大。
我刚刚删除了一组随机用户(约占总用户的80%),并且我想删除所有引用已删除用户的帖子,实际上是反加入和删除。最有效的方法是什么?
目前我有这个:
DELETE FROM posts l
WHERE NOT EXISTS
(
SELECT NULL
FROM users r
WHERE r.id = l.user_id
)
是否有更有效的方法?
答案 0 :(得分:2)
如果您要删除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;
批处理插入要比更新表中的大多数行少得多。当然,您应该仔细测试。截断表是从表中删除所有行的快速方法。
答案 1 :(得分:0)
this链接处的某人对不存在vs不存在vs左联接为空进行了一些测试。 Postgre可以判断出不存在且left-join为null就是反联接,因此进行相应的处理。因此,您的方法应该是最有效的。您可能会改组为“左联接为零”方法,但它可能不会给您带来任何好处。
预防可能会更好。使用级联删除时,外键约束是更好的选择。您在对问题的评论中提到这不是一种选择。在特定情况下不是一种选择,因为通常它是:
REFERENCES someTable(someCol) ON DELETE CASCADE ON UPDATE CASCADE