SQL反连接删除优化

时间:2018-11-07 17:01:33

标签: sql postgresql anti-join

我在postgres数据库中有两个表,postsusersposts有一个user_id外键,它引用了users.id主键列。两个表都很大。

我刚刚删除了一组随机用户(约占总用户的80%),并且我想删除所有引用已删除用户的帖子,实际上是反加入和删除。最有效的方法是什么?

目前我有这个:

DELETE FROM posts l
WHERE NOT EXISTS
  (
     SELECT NULL
     FROM users r
     WHERE r.id = l.user_id
  )

是否有更有效的方法?

2 个答案:

答案 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