我有一个配置表,其中每一行都有一个json数组{oid:" 1.1.1"实例:" 0"值:" abc"}元素。我想运行以下查询,它将返回特定元素的oid,实例和值。
SELECT c.*, d->>'oid' oid, d->>'instance' instance, d->>'value' as value
FROM configuration_bkp2 c , jsonb_array_elements(config->'data') d
WHERE (d->>'oid' = '1.3.6.1.4.1.7352.3.10.2.5.35.3' AND d->>'instance' = '0' ) OR (d->>'oid' = '1.3.6.1.4.1.7352.3.999.2.5.2' AND d->>'instance' = '0' )
order by id
如果我只查找一个{oid instance}元素并添加以下内容 部分到where子句它显着加速了事情
"where (config->'data') @> '[{"oid": "1.3.6.1.4.1.7352.3.10.2.5.35.3", "instance": "0"}]' and ..."
但是,如果我为两个元素执行
(config->'data') @> '[{"oid": "3.10.2.5.35.3", "instance": "0"}, {"oid": "3.999.2.5.2", "instance": "0"}]' it runs much slower (60ms vs 4 seconds)
如果我查找两个或更多{oid instance}
元素,我如何加快查询速度?
数据样本:
{"_x": "312", "data": [{"oid": "3.10.2.5.35.3", "value": "0", "instance": "0"}, {"oid": "3.999.2.5.2", "value": "A", "instance": "0"}]}
{"_x": "483", "data": [{"oid": "3.10.2.5.35.3", "value": "2", "instance": "0"}, {"oid": "3.855.2.1.1", "value": "55", "instance": "0"}]}
{"_x": "486", "data": [{"oid": "3.10.2.5.35.3", "value": "3", "instance": "0"}, {"oid": "3.999.2.5.2", "value": "C", "instance": "0"}]}
{"_x": "489", "data": [{"oid": "3.10.2.5.35.5", "value": "3", "instance": "0"}, {"oid": "3.999.2.888.2", "value": "15", "instance": "0"}]}
CREATE TABLE configuration (
id serial PRIMARY KEY
, config jsonb NOT NULL
);
CREATE INDEX configuration_my_idx ON configuration
USING gin ((config->'data') jsonb_path_ops);
我使用的是版本9.4,以下是对查询的两个解释分析
快 - 只有一个oid
"排序(成本= 116.34..116.39行= 19宽度= 68)(实际时间= 17.700..17.701行= 38个循环= 1)" "排序键:c.id" "排序方法:快速排序记忆:60kB" " - >嵌套循环(成本= 20.15..115.94行= 19宽度= 68)(实际时间= 16.758..17.657行= 38循环= 1)" " - > configuration_bkp2 c上的位图堆扫描(成本= 20.15..77.60行= 19宽度= 36)(实际时间= 16.730..16.908行= 38个循环= 1)" "重新检查Cond:((config - >' data' :: text)@>' [{" oid":" 1.3.6.1.4.1.7352.3 .10.2.5.35.3","实例":" 0"}]' :: jsonb)" "堆块:精确= 14" " - > configuration_my_idx上的位图索引扫描(成本= 0.00..20.14行= 19宽度= 0)(实际时间= 16.706..16.706行= 38个循环= 1)" "索引条件:((config - >' data' :: text)@>' [{" oid":" 1.3.6.1.4.1.7352.3 .10.2.5.35.3","实例":" 0"}]' :: jsonb)" " - >功能扫描jsonb_array_elements d(成本= 0.01..2.00行= 1宽度= 32)(实际时间= 0.011..0.018行= 1个循环= 38)" "过滤:(((值 - >>' oid' :: text)=' 1.3.6.1.4.1.7352.3.10.2.5.35.3' :: text)AND( (值 - >>'实例' ::文字)=' 0' ::文字))" "筛选删除的行:15" "规划时间:13.379毫秒" "执行时间:17.825 ms"
慢 - 有两个oid
"排序(成本= 76402.89..76426.46行= 9428宽度= 68)(实际时间= 4772.034..4772.035行= 76个循环= 1)" "排序键:c.id" "排序方法:快速排序记忆:97kB" " - >嵌套循环(成本= 0.01..75780.51行= 9428宽度= 68)(实际时间= 12.621..4771.960行= 76循环= 1)" " - >在配置bkp2 c上的Seq扫描(成本= 0.00..361.90行= 18790宽度= 36)(实际时间= 0.008..3.306行= 18790循环= 1)" " - >函数扫描jsonb_array_elements d(成本= 0.01..4.00行= 1宽度= 32)(实际时间= 0.251..0.251行= 0循环= 18790)" "过滤:(((值 - >>'实例' ::文字)=' 0' ::文字)AND(((值 - >>' oid' :: text)=' 1.3.6.1.4.1.7352.3.10.2.5.35.3' :: text)或((value - >>' oid' :: text)=' 1.3.6.1.4.1.7352.3.999.2.5.2' :: text))AND(((((c .config - >' data' ::文字)@>' [{" oid":" 1.3.6.1.4.1.7352.3.10.2.5.35.3","实例": " 0"},{" oid":" 1.3.6.1.4.1.7352.3.999.2.5.2"," instance":& #34; 0"}]' :: jsonb)AND((值 - >>' oid' :: text)=' 1.3.6.1.4.1.7352.3 .10.2.5.35.3' :: text))或((值 - >>' oid' :: text)=' 1.3.6.1.4.1.7352.3.999.2。 5.2' ::文本)))" "筛选删除的行:444" "计划时间:0.225毫秒" "执行时间:4772.250 ms"