0Pricing
SQL Academy · 课时

使用 GIN 为 JSONB 建立索引

为 JSONB 文档建立 GIN 索引,并使用 jsonb_path_ops 加速包含查询

使用 GIN 为 JSONB 建立索引 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

为什么 JSONB 使用 GIN

JSONB 文档包含许多“项目”(键值对和数组元素)。GIN(通用倒排索引)专门用于“查找文档包含 X 的行”这类查询。

默认 GIN 索引

默认运算符类支持 @>、?、?| 和 ?&:

CREATE INDEX events_data_gin ON events USING GIN (data);

-- These now use the index:
SELECT * FROM events WHERE data @> '{"type":"login"}';
SELECT * FROM events WHERE data ? 'error';

jsonb_path_ops:更小且更快

对于仅查询包含关系的场景,它的大小只有一半且速度更快,但 ONLY 支持 @>:

CREATE INDEX events_data_gin ON events USING GIN (data jsonb_path_ops);

-- Supports @>
-- Does NOT support ?  ?|  ?&
SELECT * FROM events WHERE data @> '{"type":"login"}';

只为一个路径建立索引

如果您只查询一个键,那么在提取出的值上建立表达式 B 树索引会更快:

CREATE INDEX events_user_id_idx
  ON events (((data->>'user_id')::BIGINT));

SELECT * FROM events WHERE (data->>'user_id')::BIGINT = 42;

为数组内部建立索引

在数组路径上使用 GIN 索引:

CREATE INDEX events_tags_gin
  ON events USING GIN ((data->'tags'));

SELECT * FROM events WHERE data->'tags' @> '["admin"]'::JSONB;

将 JSONB 索引与其他筛选条件结合

复合谓词可以使用 GIN 索引处理 JSONB 部分,同时使用另一个索引处理非 JSONB 部分:

EXPLAIN ANALYZE
SELECT * FROM events
WHERE data @> '{"type":"login"}'
  AND ts >= NOW() - INTERVAL '7 days';
-- BitmapAnd: GIN index on data, B-tree on ts

GIN 写入性能

GIN 更新的开销比 B 树更大。对于写入非常频繁的表,fastupdate 选项会将 GIN 更新批量放入待处理列表,再由 VACUUM 刷新。

CREATE INDEX events_data_gin ON events USING GIN (data) WITH (fastupdate = on);

-- Flush manually if needed:
SELECT gin_clean_pending_list('events_data_gin');

索引大小

JSONB GIN 索引可能很大。对于超大表,请考虑:

  • 只为特定路径建立索引(表达式索引)
  • 对于仅查询包含关系的场景切换到 jsonb_path_ops
  • 将高频字段拆分为真正的列

与三元组索引结合

对于 JSONB 内的模糊文本搜索,请将内容提取为 TEXT 表达式,并添加 pg_trgm GIN 索引:

CREATE INDEX events_message_trgm
  ON events USING GIN ((data->>'message') gin_trgm_ops);

何时建立索引没有帮助

如果筛选条件涉及每一行(选择性非常低),即使存在索引,规划器也可能选择顺序扫描。请使用 EXPLAIN ANALYZE 进行确认。

维护 JSONB 索引

GIN 索引和其他索引一样会膨胀。请定期使用 REINDEX CONCURRENTLY:

REINDEX INDEX CONCURRENTLY events_data_gin;

总结

GIN 可以将 JSONB 筛选转换为毫秒级查找。

  • 默认 GIN:@>、?、?|、?&
  • jsonb_path_ops:更小,仅支持包含关系
  • 对提取出的标量建立表达式 B 树索引:单键查询最快

快速检查

您只会对 JSONB 列执行 data @> ... 查询。哪个索引在完整功能支持下大小最小?

常见问题解答

「使用 GIN 为 JSONB 建立索引」课时是免费的吗?

是的 — 「使用 GIN 为 JSONB 建立索引」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「使用 GIN 为 JSONB 建立索引」这节课中我会学到什么?

为 JSONB 文档建立 GIN 索引,并使用 jsonb_path_ops 加速包含查询 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「使用 GIN 为 JSONB 建立索引」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. JSONB 与 JSON:如何选择
  2. 路径操作符:-> ->> @>
  3. 使用 GIN 为 JSONB 建立索引
  4. 建模:何时 JSONB 优于规范化
← 返回 SQL Academy