在PostgreSQL中优化查询

时间:2018-11-01 13:50:40

标签: sql postgresql query-optimization

CREATE TABLE master.estado_movimiento_inventario
(
  id integer NOT NULL,
  eliminado boolean NOT NULL DEFAULT false,
  fundamentacion text NOT NULL,
  fecha timestamp without time zone NOT NULL,
  id_empresa integer NOT NULL,
  id_usuario integer NOT NULL,
  id_estado integer NOT NULL,
  id_movimiento integer NOT NULL,
  se_debio_tramitar_hace bigint DEFAULT 0,
  CONSTRAINT "PK15estadomovtec" PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE master.estado_movimiento_inventario
  OWNER TO postgres;

此表跟踪我的业务逻辑中每个库存移动的状态。因此,每个尚未结束的移动(master.estado_movimiento_inventario表中的任何id_movimiento都没有任何id_estado = 3或id_estado = 4)必须在其最后状态的se_debio_tramitar_hace字段中存储{{1} }和now()字段,每次运行计划任务时(Windows)。

为此构建的查询是这样的:

fecha

这可以按预期工作,但我怀疑它不是最佳的,特别是在更新操作中,这是我最大的疑问:执行此更新操作时最佳的是什么:

  • 执行当前更新   或
  • postgresql函数与此等效:

    foreach(update_time.id为row_id){          更新master.estado_movimiento_inventario mi set diferencia = now()-mi.fecha其中mi.id = row_id;      }

很抱歉,如果我不够明确,我没有太多使用数据库的经验,尽管我了解背后的理论,但对它的使用却不多。

编辑

请注意,id_estado不是每个id_movimiento唯一的,就像图片所示:

enter image description here

1 个答案:

答案 0 :(得分:1)

我认为这可以提高CTE:

with update_time as (
      select id_movimiento, max(id) as max_id
      from master.estado_movimiento_inventario 
      group by id_movimiento
      having sum( (id_estado in (2, 3))::int ) = 0
     )
update master.estado_movimiento_inventario mi 
  set diferencia = now() - mi.fecha 
  where mi.id in (select id from update_time);

如果最后一个id是处于“ 2”或“ 3”状态的ID,我将简单地这样做:

update master.estado_movimiento_inventario mi 
    set diferencia = now() - mi.fecha 
    where mi.id = (select max(mi2.id)
                   from master.estado_movimiento_inventario mi 
                   where mi2.id_movimiento = mi.id_movimiento
                  ) and
          mi.id_estado not in (2, 3);