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 > >