【发布时间】:2011-12-13 23:13:18
【问题描述】:
我有一个庞大的数据库......不是一个很大的数据库 - 总共大约 1gb 的数据。
我需要从几个表中删除一些行。例如我有一张桌子
Order
id | ... | status | ...
1 | ... | 1 | ...
...
40 | ... | 20 | ...
41 | ... | 1 | ...
...
470000 | ... | 12 | ...
现在我想删除所有有status=1的订单
我想我是这样做的:
DELETE FROM Order WHERE status=1
看起来一切都很好,很简单,但需要很长时间!当我运行此查询时,它在 40 分钟后仍以 100% 的 CPU 使用率运行......当我终止进程时,没有任何内容被删除。
当我尝试通过使用来限制范围时
DELETE FROM Order WHERE status=1 AND id
删除大约 200 行花了几分钟....
我的配置中有什么遗漏吗?我应该寻找/检查/更改什么?有什么想法为什么它如此低效?
我补充一下,我通常使用 MySQL,需要管理这个 postgres 数据库,但对 postgres 没有任何经验,所以可能很简单。
索引位于 id 列和状态列上。
表有大约 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)
没有任何类型的触发器或规则。更重要的是,我没有添加这是表的新副本,我的意思是它是通过导出/导入从其他服务器移动的。也许这在某种程度上起到了作用?
删除索引会有帮助吗?
【问题讨论】:
-
status列上有索引吗?删除语句的执行计划是怎样的? -
通过运行“EXPLAIN”命令:postgresql.org/docs/current/static/sql-explain.html
-
表格有多少行?那些状态怎么可能= 1?无论如何删除 266518 行不应该花费 40 分钟...
-
1) 表上是否定义了任何触发器(或规则)? 2)您可以删除所有索引并在之后重新创建它们(您不需要删除索引,删除一半表将导致顺序表扫描。
-
如果您发布了表定义,并且如果有其他表具有任何引用此表的
FOREIGN KEY并定义了ON DELETE操作,那就太好了。
标签: sql postgresql database-administration