此查询中性能的决定因素是什么?上层?在? JSON ->> 匹配?

问题描述 投票:0回答:1

我正在编辑一个生成 SQL WHERE 子句的 Java stringtemplate4 文件。这是生成的输出的示例:

where
campaign.id IN (
    select entity_id from campaign.measurement_metadata measurement
    where
    AND UPPER(measurement.measurement_partner) IN (
        'KOCHAVA'  , 'SPAA'  , 'IAS' 
    )
    AND (measurement.measurement_partner_metadata ->> 'enabled') =
        'true'
)
OR
flight.id IN (
    select entity_id from campaign.measurement_metadata measurement
    where
    AND UPPER(measurement.measurement_partner) IN (
        'KOCHAVA'  , 'SPAA'  , 'IAS' 
    )
    AND (measurement.measurement_partner_metadata ->> 'enabled') =
        'true'
)

很抱歉大小写不一致——当前代码就是这样。无论如何,上面的工作正常,但我对需要执行相同的子查询两次感到困扰。所以我找到了一种不同的方式来写条件:

where
EXISTS (
    select 1 from campaign.measurement_metadata measurement
    where measurement.entity_id IN (campaign.id, flight.id)
    AND UPPER(measurement.measurement_partner) IN (
        'KOCHAVA' 
    )
    AND (measurement.measurement_partner_metadata ->> 'enabled') =
        'true'
)

但我不确定如何推断这些查询的性能。使用像

UPPER
这样的函数会导致索引无效吗?索引是否可以帮助
IN
子句? JSON blob (
->>
) 中的匹配几乎会使任何类型的索引相对无效吗?直到昨天我才知道那个运营商。

实际上,我只是想知道我的新查询是否比原来的查询“不差”。但我很想了解原因。

该数据库通过 Flyway 进行管理 - 这是创建表的代码片段:

CREATE TABLE campaign.measurement_metadata
(
    created TIMESTAMP NOT NULL DEFAULT current_timestamp,
    updated TIMESTAMP NOT NULL DEFAULT current_timestamp,
    entity_id UUID NOT NULL,
    entity_type TEXT NOT NULL,
    measurement_partner TEXT NOT NULL,
    measurement_partner_metadata JSONB NOT NULL,
    PRIMARY KEY (entity_id, entity_type, measurement_partner)
);

CREATE TRIGGER set_timestamp
    BEFORE UPDATE ON campaign.measurement_metadata
    FOR EACH ROW
    EXECUTE PROCEDURE campaign.trigger_set_timestamp();

CREATE INDEX measurement_metadata_idx ON campaign.measurement_metadata (entity_id, entity_type, measurement_partner);
sql postgresql query-optimization
1个回答
0
投票

如果使用 CTE,您可以执行一次子查询,但可以使用它两次:

with entity_ids as (
    select entity_id from campaign.measurement_metadata measurement
    where
    AND UPPER(measurement.measurement_partner) IN (
        'KOCHAVA'  , 'SPAA'  , 'IAS' 
    )
    AND (measurement.measurement_partner_metadata ->> 'enabled') =
        'true'
)
select ... 
where campaign.id in (select entity_id from entity_ids)
or flight.id in (select entity_id from entity_ids)
© www.soinside.com 2019 - 2024. All rights reserved.