【问题标题】:GIN INDEX on the table, but PostgreSQL EXPLAIN shows me Seq. Scan表上的 GIN INDEX,但 PostgreSQL EXPLAIN 向我显示 Seq.扫描
【发布时间】:2021-04-19 15:03:03
【问题描述】:

我有一张桌子:

CREATE TABLE skill (
    user_id integer NOT NULL,
    data jsonb
);

和 jsonb 列上的 gin 索引:

CREATE INDEX idx_user_id_knowledge ON skill USING gin (data);

INSERT INTO skill(user_id, data)
VALUES (1, '{"technology": "PHP", "knowledge": 77 }'),
       (2, '{"technology": "PHP", "knowledge": 79 }'),
       (3, '{"technology": "PHP", "knowledge": 97 }'),
       (4, '{"technology": "MySQL", "knowledge": 85 }'),
       (5, '{"technology": "MySQL", "knowledge": 89 }');

但是当我运行 EXPLAIN 查询时:

EXPLAIN
SELECT * FROM skill
WHERE data->>'technology' = 'PHP' AND (data->>'knowledge')::NUMERIC > 50;

输出如下:

Seq Scan on skill (cost=0.00..41.75 rows=2 width=36)
Filter: (((data ->> 'technology'::text) = 'PHP'::text) AND (((data ->> 'knowledge'::text))::numeric > '50'::numeric))

为什么查询规划器不使用我创建的 gin 索引而不是 Seq.扫描?

http://sqlfiddle.com/#!17/35f2c/5

【问题讨论】:

  • 如果只选择数据会发生什么'
  • rows=2,这几乎是一个空表。索引扫描永远不会比顺序扫描快。

标签: postgresql indexing jsonb sql-execution-plan explain


【解决方案1】:

TLDR Gin 索引不适用于此类运算符。


查看operators for GIN indexes,您可以看到jsonb 类型唯一支持的运算符是:? ?& ?| @> @? @@

请参阅JSON Function and Operators 文档了解这些含义。根据您的查询,如果您这样重写查询,它只能优化文本比较:

SELECT * FROM skill
WHERE data @> '{"technology": "PHP"}' AND (data->>'knowledge')::NUMERIC > 50;

这会产生以下查询计划:

Bitmap Heap Scan on skill (cost=16.01..20.03 rows=1 width=32)
Recheck Cond: (data @> '{"technology": "PHP"}'::jsonb)
  Filter: (((data ->> 'knowledge'::text))::numeric > '50'::numeric)
  -> Bitmap Index Scan on idx_user_id_knowledge (cost=0.00..16.01 rows=1 width=0)
     Index Cond: (data @> '{"technology": "PHP"}'::jsonb)

SQLFiddle to play around in


经过进一步的摆弄,您可以改为使用直接针对这些 json 字段的普通索引:

CREATE INDEX idx_user_id_knowledge ON skill  ((data->>'technology'), ((data->>'knowledge')::NUMERIC));

可用于查询中的两个条件。

Updated fiddle

【讨论】:

  • 如果我们看一下查询计划成本,正常索引是更好的选择吗?
  • @dimmed 对于您提出的用例,是的。如果您计划扩展架构或使用不同的查询,您应该做进一步的测试。索引的正常注意事项适用于任何情况(存储和插入/更新性能)
猜你喜欢
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多