Postgres 中的性能问题 jsonb

Posted

技术标签:

【中文标题】Postgres 中的性能问题 jsonb【英文标题】:Performance issues jsonb in Postgres 【发布时间】:2015-12-15 16:52:27 【问题描述】:

我在 postgres 中遇到了 jsonb 的一些性能问题。我的数据库中有很多产品,每个产品都有一个名为 Technical_details 的列,它保存了所有技术细节,每个都像这样

 
    detail: 
        unit: unit_name,
        value: value 
    
 

例如:

 
    weight:  
        unit: ‘kg’,
        value: 1000 
     

现在我想进行如下查询:

Product Load (149.4ms) 
    SELECT "products".* FROM "products" 
    WHERE (COALESCE(CAST( nullif(technical_details#>>’weight,value','') AS FLOAT),0) BETWEEN 500 AND 1500)

但正如您所见,进行这样的查询需要很长时间。有人知道如何提高此类查询的性能吗?

非常感谢!

编辑: 正如德米特里所要求的: 这些是我拥有的与技术细节相关的指数:

"index_products_on_technical_details" gin (technical_details)
"index_products_on_technical_details_width" btree ((technical_details ->> 'width'::text))
"index_products_on_technical_details_weight" btree ((technical_details ->> 'weight'::text))

这是EXPLAIN ANALYZE 查询:

Seq Scan on products  (cost=0.00..926.80 rows=22 width=1288) (actual time=0.100..30.563 rows=498 loops=1)
   Filter: ((COALESCE((NULLIF((technical_details #>> 'weight,value'::text[]), ''::text))::double precision, 0::double precision) >= 500::double precision) AND (COALESCE((NULLIF((technical_details #>> 'weight,value'::text[]), ''::text))::double precision, 0::double precision) <= 1500::double precision))
   Rows Removed by Filter: 3997
 Planning time: 0.236 ms
 Execution time: 30.740 ms

【问题讨论】:

“真的很长时间”不是很精确的描述。您能否提供您的索引配置(\d tableName)和EXPLAIN ANALYZE 输出? “真的很长”我指的是 Rails 控制台中给出的 149.4 毫秒的产品加载时间。我用请求的信息改进了这个问题。 【参考方案1】:

您可以创建基于表达式的索引来加快速度:

create index on products (
  COALESCE(CAST(nullif(technical_details#>>'weight,value','') AS FLOAT),0)
);

当然,查看可能并非都在同一个单位中的值有点奇怪。

【讨论】:

以上是关于Postgres 中的性能问题 jsonb的主要内容,如果未能解决你的问题,请参考以下文章

Postgres jsonb null vs 空对象查询性能

有人对 ServiceStack Ormlite 中的 postgres jsonb 有问题吗?

从 Postgres 中的 JSONB 字段中选择不为空的值

JDBCTemplate RowMapper 读取 postgres 表中的 jsonb 列

postgres jsonb列中的模糊字符串匹配

如何根据 jsonb 列中的 unix 整数设置 postgres 时间戳列?