Re: Baja performance en inserts masivos con bytea

From: Milton Enrique Fajardo Garcia <milton(dot)fajardo(at)gmail(dot)com>
To: "Guillermo E(dot) Villanueva" <guillermovil(at)gmail(dot)com>, pgsql-es-ayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Baja performance en inserts masivos con bytea
Date: 2023-06-09 16:24:34
Message-ID: jabc9lmoaqh3d8ps0s1sq0a3.1686327874021@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

<html><head><style id="outgoing-font-settings">#response_container_BBPPID{font-family: initial; font-size:initial; color: initial;}</style></head><body style="background-color: rgb(255, 255, 255); background-image: initial; line-height: initial;"><div id="response_container_BBPPID" style="outline:none;" dir="auto" contenteditable="false"> <div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;">select data<br> &nbsp; &nbsp; from pg_catalog.pg_largeobject<br> &nbsp; &nbsp; where loid = l_oid<br> &nbsp; &nbsp; order by pageno</div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;"><br></div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;">Prueba a quitar ese&nbsp; "order by pageno" y revisa si obtienes los datos correctos. Para cada insert haces un orderby de todos los registros y esto de te hace demorar mucho.</div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;"><br></div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width:100%;"><br></div> <div id="blackberry_signature_BBPPID" name="BB10" dir="auto"> <div id="_signaturePlaceholder_BBPPID" name="BB10" dir="auto">Enviado mediante <a href="http://play.google.com/store/apps/details?id=com.blackberry.hub">Bandeja de entrada de BlackBerry Hub+ para Android</a></div> </div></div><div id="_original_msg_header_BBPPID" dir="auto"> <table width="100%" style="border-spacing: 0px; display: table; outline: none;" contenteditable="false"><tbody><tr><td colspan="2" style="padding: initial; font-size: initial; text-align: initial;"> <div style="border-right: none; border-bottom: none; border-left: none; border-image: initial; border-top: 1pt solid rgb(181, 196, 223); padding: 3pt 0in 0in; font-family: Tahoma, &quot;BB Alpha Sans&quot;, &quot;Slate Pro&quot;; font-size: 10pt;"> <div id="from"><b>De:</b> guillermovil(at)gmail(dot)com</div><div id="sent"><b>Enviados:</b> 9 de junio de 2023 10:58</div><div id="to"><b>Para:</b> pgsql-es-ayuda(at)postgresql(dot)org</div><div id="subject"><b>Asunto:</b> Baja performance en inserts masivos con bytea</div></div></td></tr></tbody></table> <br> </div><!--start of _originalContent --><div name="BB10" dir="auto" style="background-image: initial; line-height: initial; outline: none;" contenteditable="false"><div dir="ltr">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.<div><br></div><div>Entiendo si por la versión no pueden o no quieren aportar.</div><div><br></div><div>Cómo los datos originales tenían una columna lo (large object) los tengo que pasar a bytea, para eso utilizo la función:</div><div><font face="monospace" color="#0000ff">CREATE OR REPLACE FUNCTION public.bytea_import(IN l_oid oid, OUT p_result bytea) RETURNS bytea AS<br>$BODY$<br> declare<br> &nbsp;r record;<br> begin<br> &nbsp;p_result := E'\\x';<br> &nbsp;for r in ( select data<br> &nbsp; &nbsp; from pg_catalog.pg_largeobject<br> &nbsp; &nbsp; where loid = l_oid<br> &nbsp; &nbsp; order by pageno ) loop<br> &nbsp; &nbsp;p_result = p_result || <wbr><a href="http://r.data">r.data</a><wbr>;<br> &nbsp;end loop;<br> end;<br>$BODY$<br>LANGUAGE plpgsql;</font><br></div><div><br></div><div>El explain de la query dentro de la función es:</div><div><font face="monospace" color="#0000ff">"Index Scan using pg_largeobject_loid_pn_index on pg_largeobject &nbsp;(cost=0.00..1307.84 rows=2238 width=1093)"<br>" &nbsp;Index Cond: (loid = 123123123::oid)"</font><br></div><div><br></div><div>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:</div><div><font face="monospace" color="#0000ff">CREATE OR REPLACE FUNCTION insertar_tca() RETURNS VOID AS $$<br>DECLARE<br>&nbsp; &nbsp;ini_oid INT;<br>&nbsp; &nbsp;min_oid INT;<br>&nbsp; &nbsp;max_oid INT;<br>&nbsp; &nbsp;batch_size INT := 10000; -- Tamaño del lote para cada actualización<br>BEGIN<br>&nbsp; &nbsp;SELECT MIN(oid), MAX(oid) INTO min_oid, max_oid FROM tca;<br>&nbsp; &nbsp;ini_oid := min_oid;<br><br>&nbsp; &nbsp;WHILE min_oid &lt;= max_oid<br>&nbsp; &nbsp;LOOP<br> INSERT INTO tca_bytea<br> SELECT org_codigo, tcc_codigo, hca_numero, dac_codigo, hac_numero, hca_anio, <br> &nbsp; &nbsp; &nbsp; hac_anio, <b>bytea_import</b>(tca_texto)<br> FROM tca<br> WHERE oid &gt;= min_oid AND oid &lt; min_oid + batch_size;<br> RAISE NOTICE '[%] Registros actualizados tca desde % hasta % - Total %', current_timestamp,min_oid, min_oid + batch_size, min_oid + batch_size - ini_oid;<br><br> min_oid := min_oid + batch_size;<br>&nbsp; &nbsp;END LOOP;<br>END;<br>$$ LANGUAGE plpgsql;</font><br></div><div><br></div><div>Tengo un índice creado en la tabla origen por la columna oid y el explain del select principal de esa función es:</div><div><font color="#0000ff">"Bitmap Heap Scan on tca &nbsp;(cost=171.68..14074.21 rows=12854 width=30)"<br>" &nbsp;Recheck Cond: ((oid &gt;= 123123123::oid) AND (oid &lt; 123133123::oid))"<br>" &nbsp;-&gt; &nbsp;Bitmap Index Scan on idx_oid_tca &nbsp;(cost=0.00..168.47 rows=12854 width=0)"<br>" &nbsp; &nbsp; &nbsp; &nbsp;Index Cond: ((oid &gt;= 123123123::oid) AND (oid &lt; 123133123::oid))"</font><br></div><div><br></div><div><br></div><div>El problema es que <b>demora muchísimo!!!</b>&nbsp;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 :-(</div><div>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.</div><div><br></div><div>Estoy haciendolo en un server linux con 128Gb de RAM y 32 nucleos y algunos de los parámetros de conf son:</div><div><font color="#0000ff"># Memory Configuration<br>shared_buffers = 512MB<br>effective_cache_size = 96GB<br>work_mem = 459MB<br>maintenance_work_mem = 6GB<br><br># Checkpoint Related Configuration<br>checkpoint_completion_target = 0.9<br>wal_buffers = -1<br>checkpoint_segments = 16<br><br># Network Related Configuration<br>listen_addresses = '*'<br>max_connections = 100<br><br># Storage Configuration<br>random_page_cost = 1.1<br>effective_io_concurrency = 200<br></font><br>Les agradezco mucho si me pueden tirar ideas o comentarios de que puede estar pasando.</div><div>Abrazo</div><div><br></div></div>
<!--end of _originalContent --></div></body></html>

Attachment Content-Type Size
unknown_filename text/html 6.6 KB

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Guillermo E. Villanueva 2023-06-09 16:31:45 Re: Baja performance en inserts masivos con bytea
Previous Message Guillermo E. Villanueva 2023-06-09 15:29:27 Re: Baja performance en inserts masivos con bytea