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)
没有任何触发器或规则.更重要的是,我没有添加这是表的新副本,我的意思是它是从其他服务器移出导出/导入.也许这会以某种方式发挥作用?
删除索引会有帮助吗?
在您杀死进程后没有删除任何内容是您应该看到的内容.
删除发生在一个事务中,这意味着要么删除所有内容,要么删除任何内容.为了确保可以发生这种情况,需要在删除行之前将行复制到某处.这意味着删除250k行所需的时间与插入多行相同.在某些情况下,创建一个未删除所有内容的新表并将新表重命名为旧表可能会更快.
如果从另一个数据库移动它,如果你可以保持250k行不被插入,那么你可能会更好.
(这是一般的RDBMS智慧,而不是特定于postgresql - 有关postgres MVCC如何工作的详细信息可能会有很大差异.)