【问题标题】:Efficiently delete from one table where ID matches another table有效地从一个 ID 与另一张表匹配的表中删除
【发布时间】:2021-11-02 01:43:49
【问题描述】:

我在 PostgreSQL 数据库中有两个表,其中包含几百万条记录。 我正在尝试从一个表中删除 ID 与另一表的 ID 匹配的行。我使用了以下命令:

delete from table1 where id in (select id from table2)

上面的命令已经花费了很多时间(几个小时),这让我想知道是否有更快的方法来执行此操作。创建索引会有帮助吗?

我也按照少数人的建议尝试了使用 join 删除:

delete from table1 join table2 on table1.id = table2.id

但是上面的命令返回了一个语法错误。可以修改它以避免错误吗?

【问题讨论】:

  • 您是否尝试了exists 条件而不是IN

标签: sql postgresql indexing sql-delete postgresql-performance


【解决方案1】:

语法

您的第二次尝试在 PostgreSQL 中是不合法的 DELETE 语法。这是:

DELETE FROM table1 t1
USING  table2 t2
WHERE  t2.id = t1.id;

考虑章节"Notes" for the DELETE command

PostgreSQL 允许您通过在USING 子句中指定其他表来引用WHERE 条件中其他表的列。例如,
[...]
此语法不标准。
[...]
在某些情况下,连接样式比子选择样式更容易编写或执行更快。

索引

创建索引会有帮助吗?

索引的有用性总是取决于完整的情况。如果table1 很大,并且比table2 大得多,那么table1.id 上的索引通常会有所帮助。通常,id 将是您的 PRIMARY KEY,无论如何它都会被隐式索引...
同样通常,table2 上的索引无济于事(即使存在也不会使用。)

但就像我说的:取决于完整的情况,你透露的很少。

设置的其他细节可能会使删除成本高昂。 FK 约束、触发器、索引、并发事务持有的锁、表和索引膨胀...

table2 中的非唯一行。 (但我会假设ìd 是唯一的?)然后您将首先从table2 中提取一组唯一的ID。根据基数,一个简单的DISTINCT 或更复杂的查询技术将是有序的......

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多