我在表格中有一个JSONB列,看起来像 - {key_x: value_x}
。该表包含数十亿行。
我用它来查询它的价值 -
SELECT data->> some_key FROM tableName WHERE data ? some_key;
我在列上使用了GIN
索引,使用了query-
CREATE INDEX data_index ON tableName USING GIN (data)
)`
我必须使用很多这些查询,而且目前需要花费太多时间。
EXPLAIN (ANALYZE, BUFFERS) SELECT data->> 'somekey' FROM tableName WHERE data ? 'some_key';
返回 -
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Seq Scan on homeshubhgoethereumagethchaindata (cost=0.00..1885.42 rows=39 width=32) (actual time=1.911..15.488 rows=545 loops=1)
Filter: (data ? 'c2VjdXJlLWtleS3GJ+NCu6KAcCJRTC1SLiK6ZvkRZT0avMdL0KeGitPLNg=='::text)
Rows Removed by Filter: 37748
Buffers: shared hit=1397
Planning time: 3.574 ms
Execution time: 121.253 ms
将来会增加行数。有没有办法提高查询速度?
答案 0 :(得分:1)
从你的问题来看,你看起来在jsonb列中有单个键值记录,而不是数组。如果是这样,你是否考虑用两个带有B树索引的常规列替换这个jsonb?这将比整个json数据上的GIN-index工作得快得多。
如果需要此jsonb,您可以保留它,只需为关键字段添加常规列并将其用于搜索。当然,这意味着数据重复,但另一方面,你将获得速度增益。
<强> UPD 即可。您可以使用以下查询将json转换为列:
ALTER TABLE tableName
ADD COLUMN "key" VARCHAR,
ADD COLUMN "value" VARCHAR;
UPDATE tableName SET
key = (SELECT jsonb_object_keys(data)),
value = json ->> (SELECT jsonb_object_keys(data));
答案 1 :(得分:0)
您应该在jsonb列(而不是GIN)上使用特定的功能索引: 试试这个:
CREATE INDEX ON tableName((data->>'some_key'));