PostgreSQLでのクエリの最適化

カルロス・ゴンザレス
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;

このテーブルは、ビジネスロジック内のすべての在庫移動の状態を追跡します。だから、まだ終了していないすべての動きは(そこに任意のid_estado = 3ではないかid_estado = 4 master.estado_movimiento_inventarioテーブル内の任意のid_movimientoのために)その最後の状態の中に格納しなければならないse_debio_tramitar_haceフィールドの違いをnow()してfechaたびにスケジュールされたタスクの実行を(フィールドウィンドウズ)。

そうするために私が作成したクエリは次のとおりです。

with update_time as(
   SELECT  distinct on(id_movimiento) id 
   from master.estado_movimiento_inventario 
   where id_movimiento not in (
      select id_movimiento 
      from master.estado_movimiento_inventario 
      where id_estado = 2 or id_estado=3
   ) order by id_movimiento, id desc
)
update master.estado_movimiento_inventario mi 
  set se_debio_tramitar_hace= EXTRACT(epoch FROM now()::timestamp - mi.fecha )/3600
  where mi.id in (select id from update_time);

これは期待どおりに機能しますが、特に更新操作では最適ではないと思います。これが私の最大の疑問です。この更新操作を実行するときに何が最適かということです。

  • 現在のように更新を実行するか、
  • これに相当するpostgresql関数:

    foreach(update_time.id as row_id){update master.estado_movimiento_inventario mi set diferencia = now()-mi.fecha where mi.id = row_id; }

明確に説明していないと申し訳ありませんが、データベースの操作経験はあまりありませんが、背後にある理論は理解していますが、あまり操作していません。

編集

写真が示すように、id_estadoはid_movimientoごとに一意ではないことに注意してください。

ここに画像の説明を入力してください

ゴードン・リノフ

これにより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);

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事