0

我在 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
  )

有没有更有效的方法来做到这一点?

4

2 回答 2

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;

与更新表中的大多数行相比,批量插入的工作量要少得多。当然,您应该仔细测试。截断表是从中删除所有行的快速方法。

于 2018-11-07T22:36:05.953 回答
0

链接上的某个人对不存在、不存在和左加入为空进行了一些测试。Postgre 可以判断不存在和左连接为空是反连接,因此会相应地进行。所以你的方法应该是最有效的。您可能会重组为 left-join-is-null 方法,但它可能不会给您带来任何好处。

预防可能会更好。外键约束是更好的选择,具有级联删除功能。您在对问题的评论中提到这不是一个选项。在您的特定情况下,这不是一个选择吗,因为通常,它是:

REFERENCES someTable(someCol) ON DELETE CASCADE ON UPDATE CASCADE
于 2018-11-07T19:07:42.090 回答