我已经发布了一个类似的问题,但我必须准确一点......
这是原帖:[Postgres jsonb search in array with greater operator (with jsonb_array_elements)
如果我总结一下,
这是数据库声明(简化):
CREATE TABLE documents (
document_id int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
data_block jsonb NULL,
type varchar(10)
);
这是插入的一个例子。
INSERT INTO documents (document_id, data_block)
VALUES(878979,
{"COMMONS": {"DATE": {"value": "2017-03-11"}},
"CARS": [
{"MODEL": {"value": "FERRARI F40"}},
{"MODEL": {"value": "PORSCHE CAYENNE"}},
{"MODEL": {"value": "FERRARI Testarossa"}}
]}, 'garage');
INSERT INTO documents (document_id, data_block)
VALUES(977656,
{"INVOICE": {"TOTAL_AMOUNT": {"value": "100.00"}},
"PAYABLE_INVOICE_LINES": [
{"AMOUNT": {"value": 75.00}},
{"AMOUNT": {"value": 25.00}}
]}, 'invoices');
INSERT INTO documents (document_id, data_block)
VALUES(345,
{"INVOICE": {"TOTAL_AMOUNT": {"value": "200.00"}},
"PAYABLE_INVOICE_LINES": [
{"AMOUNT": {"value": 125.00}},
{"AMOUNT": {"value": 75.00}}
]}, 'invoices');
事实上,我可以在我的JSONB列中存储任何内容,现在我想用特定的运算符进行搜索。
查询示例:
PAYABLE_INVOICE_LINES中至少有一行大于100.00的所有文件:data_block.PAYABLE_INVOICE_LINES.AMOUNT> 100.00
所有带有CARS行的文档以' FERRARI'开头。 :data_block.CARS.MODEL喜欢' FERRARI%'
所有TOTAL_AMOUNT = 100.00
COMMONS.DATE>所有文件" 2018年4月30日"
列表中CARS.MODEL的所有文件(' PORSCHE CAYENNE')
data_block.PAYABLE_INVOICE_LINES.AMOUNT位于100.00和150.00之间的所有文件
Bref,我想查询我想要的一切。我希望通过排序限制为50个结果。
我的数据库包含数百万行,我遇到了一些性能问题...
我使用EXISTS实现了解决方案:
select *
from documents d
where exists (
select 1
from jsonb_array_elements(d.data_block -> 'PAYABLE_INVOICE_LINES') as pil
where (pil->'AMOUNT'->>'value')::decimal >= 1000)
limit 50;
这很好,但还不够......有些疑问很慢。 > 20秒。
我不知道文件的结构。我们可以插入汽车,发票,身份证,客户可以创建自己的结构。 因此,我无法轻松创建索引,也无法创建函数来准备结果。
当搜索JSON对象中的数组时,查询非常慢。喜欢PAYABLE_INVOICE_LINES。
您对如何提高性能有想法吗?