我在相关部分的数据库模式是有一个名为 User 的表,它有一个布尔字段 Admin。此字段 Admin 上有一个索引。
前一天我将完整的生产数据库恢复到我的开发机器上,然后只对数据库进行了非常小的更改,所以它们应该非常相似。
当我在我的开发机器上运行以下命令时,我得到了预期的结果:
EXPLAIN SELECT * FROM user WHERE admin IS TRUE;
Index Scan using index_user_on_admin on user (cost=0.00..9.14 rows=165 width=3658)
Index Cond: (admin = true)
Filter: (admin IS TRUE)
但是,当我在生产机器上运行完全相同的命令时,我得到了这个:
Seq Scan on user (cost=0.00..620794.93 rows=4966489 width=3871)
Filter: (admin IS TRUE)
因此,它没有使用与查询完美匹配的精确索引,而是使用了近 500 万行的顺序扫描!
然后我尝试运行EXPLAIN ANALYZE SELECT * FROM user WHERE admin IS TRUE;
,希望ANALYZE
能让 Postgres 意识到顺序扫描 500 万行不如使用索引好,但这并没有改变任何东西。
我还尝试运行REINDEX INDEX index_user_on_admin
以防索引损坏,但没有任何好处。
最后,我打了电话VACUUM ANALYZE user
,很快就解决了问题。
我对真空的主要理解是它用于回收浪费的空间。可能发生了什么会导致我的索引行为不端如此糟糕,为什么真空修复它?