Re: Optimizar Update

From: Jaime Casanova <jcasanov(at)systemguards(dot)com(dot)ec>
To: mauricio pullabuestan <jmauriciopb(at)yahoo(dot)es>
Cc: Postgres ayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Optimizar Update
Date: 2023-09-08 06:13:51
Message-ID: CAJKUy5iwPoh=D_R_u29HknsNPLEUceKiA3aEDe6qcNkk6-_Ykg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

On Thu, Sep 7, 2023 at 3:42 PM mauricio pullabuestan
<jmauriciopb(at)yahoo(dot)es> wrote:
>
> Buenas tardes.
>
> Tengo una aplicación que corro en la madrugada, crea un archivo *.scv a partir de una tabla de Visual Foxpro (1400000 registros) un directorio en Ubuntu y luego ejecuta una función en postgres que copia los datos del archivo scv a una tabla UNLOGGED en Postgresql 9.6, para luego actualizar e insertar en una tabla de producción, el problema que tengo es que todo el proceso toma alrededor de 100 minutos, de los cuales el UPDATE toma más 99% del tiempo, las 2 tablas tienen como llave campos bodega, ítem con el mismo tipo y longitud
>
> Necesito optimizar este proceso
>
> Cuál es el riesgo de desactivar un trigger y luego de procesar volverlo a activar, sabiendo que no tiene incidencia dentro de este proceso y la concurrencia es mínima.
>

Si usas ALTER TABLE DISABLE TRIGGER USER, no hay riesgo... siempre que
sepas que el trigger no hace nada importante

>
> Trigger
>
> 1 trigger de auditoria para Insert, Edit, Delete, crea un registro en una tabla con datos de los cambios.
>
> 2 trigger por truncate
>
> 3 trigger por delete que verifica que no tenga existencia u ordenes
>
> 4 trigger before por Insert, llena algunos campos con un par de select a tablas muy pequeñas
>
> 5 trigger after por trigger que inserta en un registro en una tabla.
>

aunque aqui mencionas varios triggers, sobre que tabla están estos
triggers? el 5to es sobre UPDATE?

>
>
> CREATE UNLOGGED TABLE data_igualar.item_bodega_pedidos_spp
> (
> item character varying(15) NOT NULL,
> loctid character varying(3) NOT NULL,
> lsoaloc numeric(12,3),
> orderpt numeric(12,3),
> icacct character varying(24),
> rclacct character varying(24),
> iclacct character varying(24),
> gllink character varying(3),
> com_pedido numeric(10,3),
> CONSTRAINT item_bodega_pedidos_spp_pkey PRIMARY KEY (loctid, item)
> )
>

aqui yo crearía un índice sobre item para ayudar al DELETE que haces
justo después del COPY

>
> Función
>
> CREATE FUNCTION item_bodega_fvp_pg()
> RETURNS void AS
> $BODY$
>
> BEGIN
>
> SET work_mem = '500MB';
> TRUNCATE item_bodega_pedidos_spp;
> COPY item_bodega_pedidos_spp FROM '/home/pasa_vfp_pg/bodega_migra.csv' DELIMITER ',' CSV HEADER;
>
> DELETE FROM item_bodega_pedidos_spp t
>
> WHERE NOT EXISTS (SELECT 1 FROM items i Where i.item = t.item);
>
>
> -- ALTER TABLE bodegas DISABLE TRIGGER USER;
> UPDATE bodegas b
> Set pedidos_clientes = COALESCE(t.lsoaloc, 0)
> , buffer = COALESCE(t.orderpt, 0)
> , comprometido_pedido = COALESCE(t.com_pedido, 0)
> FROM ditem_bodega_pedidos_spp t
> WHERE (b.bodega, b.item) = (t.loctid, t.item);
>
> -- ALTER TABLE bodegas ENABLE TRIGGER USER;
>
>
> /* registros insertados son muy esporádicos */
>
> INSERT INTO bodegas
> ( item, bodega, pedidos_clientes, buffer, cuenta_inventarios, cuenta_compras, cuenta_ajuste
> , codigo_integracion, comprometido_pedido)
> Select
> t.item, t.loctid, COALESCE(t.lsoaloc, 0), COALESCE(t.orderpt, 0), COALESCE(t.icacct, ''), COALESCE(t.rclacct, ''), COALESCE(t.iclacct, '')
> , COALESCE(t.gllink, ''), COALESCE(t.com_pedido, 0)
> From item_bodega_pedidos_spp t
> Where NOT EXISTS( Select 1
> From bodegas b
> WHERE (b.bodega, b.item) = (t.loctid, t.item));
>
> TRUNCATE item_bodega_pedidos_spp;
> RESET work_mem;
>
> END;
>
> $BODY$
> LANGUAGE plpgsql VOLATILE
> COST 100;
>

un explain analyze de los UPDATE e INSERT dentro de la función sería
interesante. puedes obtenerlos usando auto_explain o puedes ponerlos
en una sentencia preparada y sacar el explain de la sentencia
preparada. algo así:

"""
prepare foo as
UPDATE bodegas b
Set pedidos_clientes = COALESCE(t.lsoaloc, 0)
, buffer = COALESCE(t.orderpt, 0)
, comprometido_pedido = COALESCE(t.com_pedido, 0)
FROM ditem_bodega_pedidos_spp t
WHERE (b.bodega, b.item) = (t.loctid, t.item);

explain analyze execute foo;
"""

--
Jaime Casanova
Director de Servicios Profesionales
SystemGuards - Consultores de PostgreSQL

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Francisco Olarte 2023-09-08 07:18:37 Re: Optimizar Update
Previous Message Horacio Miranda 2023-09-07 21:06:49 Re: Optimizar Update