Hola Horacio, muchas gracias por responder, van mis rtas:

El vie, 9 jun 2023 a las 12:18, Horacio Miranda (<hmira...@gmail.com>)
escribió:

> No puedes insertar los datos en el tipo de dato de destino ?
>
de hecho eso hago, al insertar los datos llamo a la función que a partir de
un id de large object trae un bytea



>
> Evita funciones have todo por SQL las funciones te matan el performance
> siempre.
>
Perdon mi ignorancia, que son las funciones "have todo" como me recomiendas
que haga en este caso?



>
> Regards,
> Horacio Miranda
>
>
> On 9/06/2023, at 10:58 AM, Guillermo E. Villanueva <guillermo...@gmail.com>
> wrote:
>
> 
> Hola amigos cómo están? les pido ayuda, tengo una muy baja performance en
> un proceso masivo que tengo que hacer, lamentablemente es postgres 9.2 ya
> que dependemos de un 3ro.
>
> Entiendo si por la versión no pueden o no quieren aportar.
>
> Cómo los datos originales tenían una columna lo (large object) los tengo
> que pasar a bytea, para eso utilizo la función:
> CREATE OR REPLACE FUNCTION public.bytea_import(IN l_oid oid, OUT p_result
> bytea) RETURNS bytea AS
> $BODY$
> declare
>  r record;
> begin
>  p_result := E'\\x';
>  for r in ( select data
>     from pg_catalog.pg_largeobject
>     where loid = l_oid
>     order by pageno ) loop
>    p_result = p_result || r.data;
>  end loop;
> end;
> $BODY$
> LANGUAGE plpgsql;
>
> El explain de la query dentro de la función es:
> "Index Scan using pg_largeobject_loid_pn_index on pg_largeobject
>  (cost=0.00..1307.84 rows=2238 width=1093)"
> "  Index Cond: (loid = 123123123::oid)"
>
> Creo una tabla similar a la original solo que la columna de tipo lo, ahora
> es bytea y luego recorro la tabla gande con una columna de tipo lo para
> convertirla en bytea , lo hago con la siguiente función:
> CREATE OR REPLACE FUNCTION insertar_tca() RETURNS VOID AS $$
> DECLARE
>    ini_oid INT;
>    min_oid INT;
>    max_oid INT;
>    batch_size INT := 10000; -- Tamaño del lote para cada actualización
> BEGIN
>    SELECT MIN(oid), MAX(oid) INTO min_oid, max_oid FROM tca;
>    ini_oid := min_oid;
>
>    WHILE min_oid <= max_oid
>    LOOP
> INSERT INTO tca_bytea
> SELECT org_codigo, tcc_codigo, hca_numero, dac_codigo, hac_numero,
> hca_anio,
>       hac_anio, *bytea_import*(tca_texto)
> FROM tca
> WHERE oid >= min_oid AND oid < min_oid + batch_size;
> RAISE NOTICE '[%] Registros actualizados tca desde % hasta % - Total %',
> current_timestamp,min_oid, min_oid + batch_size, min_oid + batch_size -
> ini_oid;
>
> min_oid := min_oid + batch_size;
>    END LOOP;
> END;
> $$ LANGUAGE plpgsql;
>
> Tengo un índice creado en la tabla origen por la columna oid y el explain
> del select principal de esa función es:
> "Bitmap Heap Scan on tca  (cost=171.68..14074.21 rows=12854 width=30)"
> "  Recheck Cond: ((oid >= 123123123::oid) AND (oid < 123133123::oid))"
> "  ->  Bitmap Index Scan on idx_oid_tca  (cost=0.00..168.47 rows=12854
> width=0)"
> "        Index Cond: ((oid >= 123123123::oid) AND (oid < 123133123::oid))"
>
>
> El problema es que *demora muchísimo!!!* para hacer la primera vuelta de
> ciclo, es decir los primeros 10000 registros demoró poco mas de 1 hora y la
> tabla tiene 2.5 millones de registros :-(
> He probado también de hacerlo con una columna adicional en la misma tabla
> y con sentencia UPDATE, también probé de hacerlo sin particionarlo, en
> todos los casos va demasiado lento.
>
> Estoy haciendolo en un server linux con 128Gb de RAM y 32 nucleos y
> algunos de los parámetros de conf son:
> # Memory Configuration
> shared_buffers = 512MB
> effective_cache_size = 96GB
> work_mem = 459MB
> maintenance_work_mem = 6GB
>
> # Checkpoint Related Configuration
> checkpoint_completion_target = 0.9
> wal_buffers = -1
> checkpoint_segments = 16
>
> # Network Related Configuration
> listen_addresses = '*'
> max_connections = 100
>
> # Storage Configuration
> random_page_cost = 1.1
> effective_io_concurrency = 200
>
> Les agradezco mucho si me pueden tirar ideas o comentarios de que puede
> estar pasando.
> Abrazo
>
>

Reply via email to