REINDEX 危险吗?

Ada*_*tan 17 postgresql

我一直在尝试COUNT(*)使用具有主键的 150,000 行的表。它工具大约 5 分钟,所以我发现这是一个索引问题。

引用PostgreSQL 手册

REINDEX 类似于索引的删除和重新创建,因为索引内容是从头开始重建的。然而,锁定的考虑是相当不同的。REINDEX 锁定索引的父表的写入而不是读取。它还对正在处理的特定索引进行排他锁,这将阻止尝试使用该索引的读取 (...) 随后的 CREATE INDEX 锁定写入但不锁定读取;由于索引不存在,没有读取会尝试使用它,这意味着不会有阻塞,但读取可能会被迫进行昂贵的顺序扫描。

根据你自己的经验,你能告诉:

  • REINDEXING危险的?它会损害数据一致性吗?
  • 可以花很多时间吗?
  • 它是我的场景的可能解决方案吗?

更新:

对我们有用的解决方案是重新创建具有不同名称的相同索引,然后删除旧索引。

索引创建速度非常快,我们已将索引大小从 650 MB 减少到 8 MB。使用COUNT(*)withbetween只需 3 秒。

Bil*_*hor 15

重新索引并不危险,不会损害数据一致性。但是,如果您有时间关键的写入,如果表被锁定并且 DML 中止,您可能会丢失数据。

重新索引不应该花费很多时间,但通常会涉及读取整个表、对索引字段进行排序并编写新索引。鉴于时间,COUNT(*)它可能需要五分钟或更长时间。

这不太可能是索引问题。 COUNT(*)应该使用表扫描,在这种情况下不读取索引。我希望你有某种 IO 问题。

尝试使用COUNT(1)COUNT(pk_field)可能使用索引。

如果您在 Unix 或 Linux 平台上运行,您可能希望使用sar. 您可能还有一个故障磁盘,它可以显着降低 IO 速率。

具有大对象的表也可以显着增加 IO 以构造 COUNT(*) 的记录。

  • 根据wiki.postgresql.org,```COUNT(*)``` 是最好的选择:```如果你使用count(*),数据库可以自由使用任何列进行计数,这意味着它可以选择要扫描的最小覆盖索引(请注意,这就是为什么 count(*) 比 count(some_field) 好得多的原因,只要您不关心是否计算 some_field 的 null 值)。由于索引通常完全适合内存,这意味着 count(*) 通常非常快。``` (2认同)