在同一查询中选择和更新 PostgreSQL 以进行优化

Posted

技术标签:

【中文标题】在同一查询中选择和更新 PostgreSQL 以进行优化【英文标题】:Select and update a PostgreSQL in the same query in order to optimize 【发布时间】:2017-03-13 18:29:34 【问题描述】:

我正在尝试创建一个查询以从表 X 中动态更新表 Y 中的某些值。

我目前正在处理一个托管 10kk 行的数据库,我想优化处理时间。

选择:

SELECT cycle_completa.numcycle AS actual_cycle, 
    min(cycle_completa.pump1pre) AS min_pump1pre, 
    min(cycle_completa.pump2pre) AS min_pump2pre, 
    min(cycle_completa.pump3pre) AS min_pump3pre, 
    min(cycle_completa.slidevel) AS min_slidevel, 
    min(cycle_completa.slidepos) AS min_slidepos, 
    min(cycle_completa.slideforce) AS min_slideforce, 
    min(cycle_completa.slideservopilotpre) AS min_slideservopilotpre, 
    min(cycle_completa.slidecentralpre) AS min_slidecentralpre, 
    min(cycle_completa.slidelateralpre) AS min_slidelateralpre, 
    min(cycle_completa.slideringpre) AS min_slideringpre, 
    min(cycle_completa.slidepistonpre) AS min_slidepistonpre, 
    min(cycle_completa.slidey42pre) AS min_slidey42pre, 
    min(cycle_completa.cushionforce) AS min_cushionforce, 
    min(cycle_completa.cushionservopilotpre) AS min_cushionservopilotpre,
    min(cycle_completa.cushionpistonpre) AS min_cushionpistonpre, 
    min(cycle_completa.cushionringpre) AS min_cushionringpre, 
    min(cycle_completa.pfillaccumpre) AS min_pfillaccumpre, 
    min(cycle_completa.pfillcentralpre) AS min_pfillcentralpre, 
    min(cycle_completa.pfilllateralpre) AS min_pfilllateralpre, 
    min(cycle_completa.pfillunlockingpre) AS min_pfillunlockingpre, 
    min(cycle_completa.reducedauxpumppre) AS min_reducedauxpumppre,
    min(cycle_completa.tankoiltemp) AS min_tankoiltemp
FROM cycle_completa
WHERE slidestage = 17
GROUP BY cycle_completa.numcycle

更新:

UPDATE cycle_parametros
SET seg3_min_valor_fmant_pump1pre = min_pump1pre,
    seg3_min_valor_fmant_pump2pre = min_pump2pre,
    seg3_min_valor_fmant_pump3pre = min_pump3pre,
    seg3_min_valor_fmant_slidevel = min_slidevel,
    seg3_min_valor_fmant_slidepos = min_slidepos,
    seg3_min_valor_fmant_slideforce = min_slideforce,
    seg3_min_valor_fmant_slideservopilotpre = min_slideservopilotpre,
    seg3_min_valor_fmant_slidecentralpre = min_slidecentralpre,
    seg3_min_valor_fmant_slidelateralpre = min_slidelateralpre,
    seg3_min_valor_fmant_slideringpre = min_slideringpre,
    seg3_min_valor_fmant_slidepistonpre = min_slidepistonpre,
    seg3_min_valor_fmant_slidey42pre = min_slidey42pre,
    seg3_min_valor_fmant_cushionforce = min_cushionforce,
    seg3_min_valor_fmant_cushionservopilotpre = min_cushionservopilotpre,
    seg3_min_valor_fmant_cushionpistonpre = min_cushionpistonpre,
    seg3_min_valor_fmant_cushionringpre = min_cushionringpre,
    seg3_min_valor_fmant_pfillaccumpre = min_pfillaccumpre,
    seg3_min_valor_fmant_pfillcentralpre = min_pfillcentralpre,
    seg3_min_valor_fmant_pfilllateralpre = min_pfilllateralpre,
    seg3_min_valor_fmant_pfillunlockingpre = min_pfillunlockingpre,
    seg3_min_valor_fmant_reducedauxpumppre = min_reducedauxpumppre,
    seg3_min_valor_fmant_tankoiltemp = min_tankoiltemp
WHERE numcycle = actual_cycle

谢谢!

【问题讨论】:

【参考方案1】:

以下查询应该有效:

WITH selected as (
    SELECT cycle_completa.numcycle AS actual_cycle, 
        min(cycle_completa.pump1pre) AS min_pump1pre, 
        min(cycle_completa.pump2pre) AS min_pump2pre, 
        min(cycle_completa.pump3pre) AS min_pump3pre, 
        min(cycle_completa.slidevel) AS min_slidevel, 
        min(cycle_completa.slidepos) AS min_slidepos, 
        min(cycle_completa.slideforce) AS min_slideforce, 
        min(cycle_completa.slideservopilotpre) AS min_slideservopilotpre, 
        min(cycle_completa.slidecentralpre) AS min_slidecentralpre, 
        min(cycle_completa.slidelateralpre) AS min_slidelateralpre, 
        min(cycle_completa.slideringpre) AS min_slideringpre, 
        min(cycle_completa.slidepistonpre) AS min_slidepistonpre, 
        min(cycle_completa.slidey42pre) AS min_slidey42pre, 
        min(cycle_completa.cushionforce) AS min_cushionforce, 
        min(cycle_completa.cushionservopilotpre) AS min_cushionservopilotpre,
        min(cycle_completa.cushionpistonpre) AS min_cushionpistonpre, 
        min(cycle_completa.cushionringpre) AS min_cushionringpre, 
        min(cycle_completa.pfillaccumpre) AS min_pfillaccumpre, 
        min(cycle_completa.pfillcentralpre) AS min_pfillcentralpre, 
        min(cycle_completa.pfilllateralpre) AS min_pfilllateralpre, 
        min(cycle_completa.pfillunlockingpre) AS min_pfillunlockingpre, 
        min(cycle_completa.reducedauxpumppre) AS min_reducedauxpumppre,
        min(cycle_completa.tankoiltemp) AS min_tankoiltemp
    FROM cycle_completa
    WHERE slidestage = 17
    GROUP BY cycle_completa.numcycle
)
UPDATE cycle_parametros cp
SET cp.seg3_min_valor_fmant_pump1pre = s.min_pump1pre,
    cp.seg3_min_valor_fmant_pump2pre = s.min_pump2pre,
    cp.seg3_min_valor_fmant_pump3pre = s.min_pump3pre,
    cp.seg3_min_valor_fmant_slidevel = s.min_slidevel,
    cp.seg3_min_valor_fmant_slidepos = s.min_slidepos,
    cp.seg3_min_valor_fmant_slideforce = s.min_slideforce,
    cp.seg3_min_valor_fmant_slideservopilotpre = s.min_slideservopilotpre,
    cp.seg3_min_valor_fmant_slidecentralpre = s.min_slidecentralpre,
    cp.seg3_min_valor_fmant_slidelateralpre = s.min_slidelateralpre,
    cp.seg3_min_valor_fmant_slideringpre = s.min_slideringpre,
    cp.seg3_min_valor_fmant_slidepistonpre = s.min_slidepistonpre,
    cp.seg3_min_valor_fmant_slidey42pre = s.min_slidey42pre,
    cp.seg3_min_valor_fmant_cushionforce = s.min_cushionforce,
    cp.seg3_min_valor_fmant_cushionservopilotpre = s.min_cushionservopilotpre,
    cp.seg3_min_valor_fmant_cushionpistonpre = s.min_cushionpistonpre,
    cp.seg3_min_valor_fmant_cushionringpre = s.min_cushionringpre,
    cp.seg3_min_valor_fmant_pfillaccumpre = s.min_pfillaccumpre,
    cp.seg3_min_valor_fmant_pfillcentralpre = s.min_pfillcentralpre,
    cp.seg3_min_valor_fmant_pfilllateralpre = s.min_pfilllateralpre,
    cp.seg3_min_valor_fmant_pfillunlockingpre = s.min_pfillunlockingpre,
    cp.seg3_min_valor_fmant_reducedauxpumppre = s.min_reducedauxpumppre,
    cp.seg3_min_valor_fmant_tankoiltemp = s.min_tankoiltemp
FROM selected AS s
WHERE cp.numcycle = s.actual_cycle

【讨论】:

就是这样!我只需要更改 UPDATE cycle_parametros cp,不带“cp”,并更改所有名称,因为 PostgreSQL 给了我一个错误

以上是关于在同一查询中选择和更新 PostgreSQL 以进行优化的主要内容,如果未能解决你的问题,请参考以下文章

从 postgresql 数据库中选择值并根据我需要完整查询插入/更新

Django / PostgresQL jsonb (JSONField) - 将选择和更新转换为一个查询

使用 mysqli 在同一查询中选择和插入/更新

如何在同一个sql查询中更新和选择记录

单个 postgresql 查询中的文本和 jsonb 连接

PostgreSQL nextval 和 currval 在同一个查询中