我一直在尝试COUNT(*)
使用包含主键的150,000行的表。它用了大约5分钟的时间,所以我发现这是一个索引问题。
引用PostgreSQL手册:
REINDEX与删除索引和重新创建索引相似,因为索引内容是从头开始重建的。但是,锁定注意事项却大不相同。REINDEX锁定对索引的父表的写入但不对其进行读取。它还对正在处理的特定索引采取排他锁,这将阻止尝试使用该索引的读取(...)。后续的CREATE INDEX锁定写入但不读取;由于索引不存在,因此不会进行任何读取尝试,这意味着将不存在阻塞,但可能会将读取强制进行昂贵的顺序扫描。
根据您自己的经验,您能否告诉您:
- 有
REINDEXING
危险吗?会损害数据一致性吗? - 会花费很多时间吗?
- 这是我的情况的可能解决方案吗?
更新:
对我们有用的解决方案是使用不同的名称重新创建相同的索引,然后删除旧索引。
索引创建非常快,我们将索引大小从650 MB减小到8 MB。使用COUNT(*)
with between
只需3秒。
COUNT(*)
是最佳选择:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.