我需要删除一个非常大的表(例如 500 万行)的大部分(例如 90%)。该表的另外 10% 被频繁读取,但不被写入。
From "按 ID 删除数百万行的最佳方法”,我认为我应该删除要删除的 90% 上的所有索引,以加快该过程(除了我用来选择要删除的行的索引)。
From "PostgreSQL 锁定模式“,我看到此操作将获得ROW EXCLUSIVE
锁定整个表。但由于我只是reading另外10%,这应该不重要。
那么,在一个命令中删除所有内容是否安全(即DELETE FROM table WHERE delete_flag='t'
)?我担心如果删除一行失败,会触发enormous回滚,那么它将影响我从表中读取的能力。批量删除会更明智吗?
-
索引通常对于 90% 的行的操作是无用的。无论哪种方式,顺序扫描都会更快。 (特殊情况除外。)
-
如果需要允许并发读取,则不能在表上使用排他锁。因此,您也不能在同一事务中删除任何索引。
-
You could删除单独事务中的索引,以将独占锁的持续时间保持在最短水平。在 Postgres 9.2 或更高版本中,您还可以使用同时删除索引,只需要最少的锁。稍后使用CREATE INDEX CONCURRENTLY
在后台重建索引 - 并且只采取非常短暂的独占锁定。
如果您有稳定的条件来识别保留的 10%(或更少)行,我建议部分索引仅在这些行上获得最佳效果:
- 读取查询可以随时快速访问表(使用部分索引)。
- The big
DELETE
根本不会修改部分索引,因为没有任何行参与DELETE
.
CREATE INDEX foo (some_id) WHERE delete_flag = FALSE;
假设delete_flag
is boolean
。您必须在查询中包含相同的谓词(即使它看起来在逻辑上是多余的)以确保 Postgres 可以使用部分索引。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)