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 操作类。