JSONB字段上GIN索引与非GIN索引的效率对比及选型
问题
假设我们有一张名为api的表,其中包含一个JSONB类型的jdoc列,数据结构如下:
{ "guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a", "name": "Angela Barton", "is_active": true, "company": "Magnafone", "address": "178 Howard Place, Gulf, Washington, 702", "registered": "2009-11-07T08:53:22 +08:00", "latitude": 19.793713, "longitude": 86.513373, "tags": [ "enim", "aliquip", "qui" ] }
最常用的查询是基于company字段的:
SELECT jdoc FROM api WHERE jdoc->>'company'='Magnafone'
请问创建以下哪种索引效率更高,并说明原因:
选项一:
CREATE INDEX idx ON api USING GIN (jdoc);
选项二:
CREATE INDEX idx ON api (jdoc->>'company')
答案
选项二的索引效率更高,原因如下:
- 完全匹配查询需求:选项二是直接针对查询里用到的
jdoc->>'company'表达式创建的B-tree索引(PostgreSQL默认索引类型为B-tree),和查询的过滤条件完全契合,查询时可直接通过索引定位目标行,无需额外计算。 - 索引体积更小,资源开销低:选项一的GIN索引会存储JSONB字段中所有键值对、数组元素的索引条目,相比仅存储
company字段值的B-tree索引,体积大得多。更大的索引意味着更多磁盘IO和内存占用,查询性能自然受影响。 - 查询逻辑更简洁:使用选项二的索引时,PostgreSQL直接查找等于
Magnafone的条目即可;而使用GIN索引时,需要先解析JSON结构,再匹配company键对应的Magnafone值,多了一层解析步骤,会带来额外性能开销。
不过要是后续有大量针对该JSONB字段其他键或数组的查询,GIN索引的灵活性会更有优势,但仅针对当前这个常用查询,选项二是更高效的选择。
内容的提问来源于stack exchange,提问作者Ekaterina
相关产品推荐
相关产品推荐

