我有一个表,该表的列为hstore数组。在JSON表示法中,该字段的数据如下:
[
{ type: "Pickup", id: "49593034" },
{ type: "User", id: "5903" },
...
]
单个记录在数组中的hstore数量可能高达10,000,尽管可能更少。该表仅接收插入。添加记录后,不会删除或更新任何数据。
此表中目前大约有9万条记录,并且通常每天增加几百条。较早记录中的值可能具有与较早记录中的值不同的ID。
我需要能够在此列上进行搜索。例如,我可能想知道此列包含'type=>User,id=>5903'::hstore
的所有记录。我发现如果我在此列上创建了GIN索引并使用&&
运算符查询,它就能非常快速地搜索此数据。
我遇到了一个问题,该查询的膨胀程度很高。 PG停止使用该索引,并切换到表扫描,导致它非常慢。我通过在索引上运行REINDEX
来解决此问题。
我发现肿胀过了一会儿又回来了。尽管它没有再次切换到表扫描(即使膨胀很大),但我担心它会在我再次看到它变高时抢先进行重新索引。每当执行此操作时,都必须使函数脱机,因为重新编制索引会根据文档阻止该索引的使用。
我正在使用Heroku的PG服务,他们提供了一种查询膨胀的工具。可以在here中找到它执行的查询。
执行REINDEX
后,索引大小约为1GB。根据Heroku的查询,它膨胀时会增长到11GB左右。
我的问题是:
DELETE
或UPDATE
会导致膨胀。数据的添加是否导致它不得不重新平衡一棵树或其他导致索引中的页面失效的东西?我当时正在考虑对其进行重构,以便将该列中的数据存储在单独的表中。这个单独的表会将主表的类型,ID和ID存储为单独的列。我将在type
和id
字段上创建btree索引。这会给我一个一般免维护的查询吗?我认为这样做也会更快,因为id
可以存储为真实数字。目前,它存储为字符串,因为hstore值始终是字符串。