我在PostgreSQL中有一个包含一个JSONB列的表。JSON看起来像这样-{'key':some_key, 'value': some_value}
。
我在JSON中使用-
CREATE INDEX t3_index ON t3 USING GIN ((data->'key'));
table的表面看起来像-
Table "public.t3"
Column | Type | Collation | Nullable | Default
--------+-------+-----------+----------+---------
data | jsonb | | |
Indexes:
"t3_index" gin ((data -> 'key'::text))
当我使用key
查询时,PostgreSQL正在进行序列扫描。
psql_eth=> explain (analyze, buffers) select * from t3 where data->>'key'='ZGJVcGdyYWRlXzIwMTcwNzE0ZGVkdXBsaWNhdGVEYXRh';
QUERY PLAN
----------------------------------------------------------------------------------------------------
Seq Scan on t3 (cost=0.00..4201.65 rows=377 width=289) (actual time=0.017..42.976 rows=1 loops=1)
Filter: ((data ->> 'key'::text) = 'ZGJVcGdyYWRlXzIwMTcwNzE0ZGVkdXBsaWNhdGVEYXRh'::text)
Rows Removed by Filter: 75049
Buffers: shared hit=3142
Planning time: 0.068 ms
Execution time: 42.996 ms
(6 rows)
1.为什么PostgreSQL要进行seq扫描?
1.如何使查询结果更快?如何使其使用GIN索引?
2条答案
按热度按时间nx7onnlm1#
来自文档:
jsonb的默认GIN运算符类支持使用顶级键存在运算符?、?&和?的查询|运算符和路径/值存在运算符@〉。
该索引不适用于相等运算符(=)。可以改用简单的btree索引:
o0lyfsai2#
迟到了,但如果它仍然有帮助,见下文。
您已经使用了
CREATE INDEX t3_index ON t3 USING GIN ((data->'key'));
就像documentation说的-
对于类型jsonb,jsonb_ops是默认值。
由于您没有提供任何运算符类,因此将为您选择默认值。
对于
jsonb_ops
运算符类,仅支持以下运算符-??&?|@〉@?@@
=
不在上述列表中,因此不受支持,即无法使用索引。您可以改为将where子句更改为使用
@>
,然后重试-对于小表- planner可能仍然会选择Seq Scan,因为它可能会更快。但是既然你说你的表有
712313
行,@>
方法肯定会使用GIN索引。