我有一个9.4 Postgres数据库,其中有一个包含jsonb
字段的表。
json的结构看起来与此类似:
{
name: 'customer1',
age: 28,
products: [{
name: 'product1',
price: 100
}, {
name: 'product2',
price: 200
}]
}
以下查询返回上述json就好了:
SELECT jdoc
FROM customers, jsonb_array_elements(jdoc->'products') as products
WHERE (products->>'price')::numeric > 150
问题是大型数据库的性能会受到很大影响。
我可以使用什么索引来加速此查询?
我尝试过的目标:
GIN
个索引(jsonb_ops
和jsonb_path_ops
)。它们似乎只适用于像@>
这样的存在运算符。
CREATE INDEX ON persons(((jsonb_array_elements(jdoc->'products')->>'price')::numeric))
。哪个给我发数据类型不匹配错误。
CREATE INDEX ON persons(((jdoc->'age')::numeric))
有效且允许我快速查询(jdoc->>'age')::numeric < 30
。答案 0 :(得分:2)
你可以创建一个函数并使用它:
CREATE FUNCTION max_price(jsonb) RETURNS double precision
LANGUAGE sql IMMUTABLE AS
$$SELECT max(p.price)
FROM jsonb_to_recordset($1->'products')
AS p(name text, price double precision)$$;
CREATE INDEX customers_ind ON customers(max_price(jdoc));
然后这个索引可以用于这样的查询:
EXPLAIN SELECT jdoc FROM customers WHERE max_price(jdoc) > 150;
QUERY PLAN
--------------------------------------------------------------------------------
Index Scan using customers_ind on customers (cost=0.12..8.14 rows=1 width=36)
Index Cond: (max_price(jdoc) > '150'::double precision)
(2 rows)
这不是您的查询,但它应该是等效的。