提高包含数十亿行的PostgreSQL JSONB列的查询速度

时间:2017-12-29 12:14:15

标签: sql postgresql

我在表格中有一个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

将来会增加行数。有没有办法提高查询速度?

2 个答案:

答案 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'));