我有桌子:
Settings 有类似 {id: int, stage_type: int} 的数组。 例如:[{id: 1, stage_type: 2}, {id: 2, stage_type: 5}]
如果 current_stage_id 属于某种阶段类型,我需要查询请求。有很多选择和很多请求 - 所以我需要使用索引或其他。
我创建了索引 - 但它没有被使用。 使用 gin 创建索引 ix_selection_stage_setting ON 选择(设置 jsonb_path_ops);
当前请求如下所示:
with stage_settings as (SELECT stage.id as stage_id, stage.stage_type, rs.id as selection_id
FROM selection rs,
jsonb_to_recordset(rs.settings) AS stage(id INT, stage_type INT))
SELECT r.id, r.selection_id, r.current_stage_id
FROM request r
JOIN stage_settings ss on ss.stage_id = r.current_stage_id AND ss.selection_id = r.selection_id
WHERE ss.stage_type = 1;
我需要更改它以使用索引或其他优化。物化视图被一位高级员工拒绝了。
数据模型很糟糕。如果您存储键值对数组而不是以关系方式对其进行建模,这就是您所得到的结果。
您的查询不可能表现良好。
如果按如下方式重写查询,如果
request
不是太大,它有可能会更快:
SELECT r.id, r.selection_id, r.current_stage_id
FROM request AS r
WHERE EXISTS (SELECT FROM selection AS rs
WHERE r.selection_id = rs.id
AND rs.settings @> jsonb_build_object(
'id', r.current_stage_id,
'stage_type', 1
)
);
除了 GIN 索引之外,您还应该在
selection.id
上拥有一个索引(如果它还不是您的主键)。
如果
selection
很小,以下版本可能会更好:
SELECT DISTINCT
r.id, r.selection_id, r.current_stage_id
FROM request AS r
JOIN selection AS rs
ON r.selection_id = rs.id
AND rs.settings @> jsonb_build_object(
'id', r.current_stage_id,
'stage_type', 1
);