Postgres 9超慢速简单删除

Ran*_*ash 8 sql postgresql database-administration

我有一个实质性的数据库...不是一个非常大的数据库 - 总共约1GB的数据.

我需要从几个表中删除一些行.例如,我有一张桌子

 Order
 id     | ... | status   | ...
 1      | ... | 1        | ...
 ...
 40     | ... | 20       | ...
 41     | ... | 1        | ...
 ...
 470000 | ... | 12       | ...
Run Code Online (Sandbox Code Playgroud)

现在我要删除所有的订单 status=1

我认为我这样做:

DELETE FROM Order WHERE status = 1

看起来很简单,但需要很长时间!当我运行此查询时,它仍然在40分钟后以100%的CPU使用率运行...当我杀死进程时没有删除任何内容.

当我尝试使用时限制范围

DELETE FROM Order WHERE status = 1 AND id <1000

删除约200行需要几分钟....

我的配置中是否有任何遗漏?我应该寻找/检查/改变什么?任何想法都是为什么它如此血腥低效?

让我补充一点,我通常使用MySQL并且需要管理这个postgres数据库但是对postgres没有任何经验,所以它可能非常简单.

索引同时包含id和status列.

表有大约500k行,大约一半需要删除.

执行计划:

Delete  (cost=0.00..19474.19 rows=266518 width=6)
->  Seq Scan on Orders  (cost=0.00..19474.19 rows=266518 width=6)
Filter: (statusid = 1)
Run Code Online (Sandbox Code Playgroud)

没有任何触发器或规则.更重要的是,我没有添加这是表的新副本,我的意思是它是从其他服务器移出导出/导入.也许这会以某种方式发挥作用?

删除索引会有帮助吗?

evi*_*tto 9

在您杀死进程后没有删除任何内容是您应该看到的内容.

删除发生在一个事务中,这意味着要么删除所有内容,要么删除任何内容.为了确保可以发生这种情况,需要在删除行之前将行复制到某处.这意味着删除250k行所需的时间与插入多行相同.在某些情况下,创建一个未删除所有内容的新表并将新表重命名为旧表可能会更快.

如果从另一个数据库移动它,如果你可以保持250k行不被插入,那么你可能会更好.

(这是一般的RDBMS智慧,而不是特定于postgresql - 有关postgres MVCC如何工作的详细信息可能会有很大差异.)