PostgreSQL 不同 GIN 索引的区别

GIN(Generalized Inverted Index)是 PostgreSQL 的倒排索引,适合一个字段包含多个可搜索元素的场景,典型应用包括 jsonb、数组和全文检索。

JSONB 的两种 GIN

jsonb 默认使用 jsonb_ops

CREATE INDEX idx_data_gin ON users USING GIN (data);

它支持的操作符较完整,包括 @><@??|?& 等。

jsonb_path_ops 需要显式指定:

CREATE INDEX idx_data_gin ON users USING GIN (data jsonb_path_ops);

它主要支持 @> 包含查询,索引通常更小,在大量 JSON 包含查询场景下效率较好,但不支持键存在性查询。

类型 主要用途 特点
jsonb_ops 通用 JSONB 查询 功能完整,默认选择
jsonb_path_ops JSONB @> 查询 索引更小,针对性更强
数组 GIN 数组包含、交集 查询数组元素
tsvector GIN 全文检索 查询文本词项

不要把 JSONB 查询都交给 GIN

例如:

WHERE data->>'user_id' = '123'

如果 user_id 是固定字段且经常精确查询,通常应该建立 B-tree 表达式索引:

CREATE INDEX idx_user_id ON users ((data->>'user_id'));

而:

WHERE data @> '{"role":"admin"}'

则更适合使用 JSONB GIN。

因此,GIN 的核心不是“JSONB 专用索引”,而是通用倒排索引机制。实际选型应根据查询操作符决定:需要完整 JSONB 操作支持使用 jsonb_ops,主要进行 @> 查询可以考虑 jsonb_path_ops;数组和全文检索则分别使用对应的 GIN 操作类。

如果你有魔法,你可以看到一个评论框~