FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Velocidad al grabar multiples registros en Mysql
Posts: 318
Joined: Fri Jan 14, 2022 08:37 AM
Velocidad al grabar multiples registros en Mysql
Posted: Tue Aug 06, 2024 11:17 AM
Hola,

Todos los dias subo la tabla de ventas a un servidor mysql
El problema es que ya demora mucho.
La voy subiendo registro a registro con la siguiente estrategia y queria saber a ver a vds. que se les ocurre para mejorar la velocidad.
Desde ya gracias

Code (fw): Select all Collapse
cSetKey:= ConstruyeSet(aCamKey, cAlias)     
cSet   := ConstruyeSet(aCam   , cAlias)


cSql:= "INSERT INTO "+ cTablaSede+ Space(1)+;
               "SET "+ cSetKey+ If(Empty(cSetKey), "", ",")+ Space(1)+;
                cSet+ Space(1)+;
               "ON DUPLICATE KEY UPDATE "+ cSet

IF !oServer:Execute(cSql)
   MERROR_("(1) Fallo en ejecucion sql", cSql)
ENDIF
RETURN NIL
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Tue Aug 06, 2024 12:16 PM
Hola Paquito:
Si haces el insert o update registro por registro, eso implica que hagas tantas ejecuciones insert como registros tengas.
Podrías hace una sola query para actualizar todos los registros de una sola vez.
De esta forma podrías hacerlo a mano asi
Code (fw): Select all Collapse
dbf->(DBGOTOP())
cSql := "INSERT INTO ventas "+;
        " (factura,importe,iva,cliente) VALUES "
DO WHILE !dbf->(Eof())
    cSql := cSql + "("+ClipValue2SQL(dbf->factura) + "," + ;
                       ClipValue2SQL(dbf->importe) + "," + ;
                       ClipValue2SQL(dbf->iva) + "," + ;
                       ClipValue2SQL(dbf->cliente) + "), "
    dbf->(DbSkip())
ENDDO
cSql := LEFT(cSql,LEN(cSql)-2)  // Le borro la ultima coma y espacio
cSql := cSql + "ON DUPLICATE KEY UPDATE "+;
                     "importe = VALUES(importe), "+;
                     "iva = VALUES(iva) "
TRY
  oServer:BeginTransaction()
  oServer:Execute(cSql)
  oServer:CommitTransaction()
CATCH cError
  MsgStop("Error al Importar"+CHR(10)+cError:description,"Error")
  oServer:RollBack()
END TRY
La clase TDolphin tiene un metodo para hacerlo de forma automática
Code (fw): Select all Collapse
oServer:InsertFromDbf( cTable, cAlias, nLimit, aStruct, bOnInsert, cDuplicateKey, bOnRow )
Seguramente la clase nativa tiene algo similar
https://forums.fivetechsupport.com/viewtopic.php?f=3&t=32657
Espero te sirva de base para tu caso
Posts: 1772
Joined: Thu Sep 05, 2019 05:32 AM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Tue Aug 06, 2024 12:40 PM
hi,

you speedup a lot when send multiple INSERT Commands in "one line", depend on Cache Configuration of SQL-Server
Code (fw): Select all Collapse
LOCAL nBatchSize := 1500                                              // MTU
...
   // for every Record
   //
   cPreText := "INSERT INTO " + xtab + " VALUES("
...
   DO WHILE .NOT. EOF()
      nCount ++
      lUseBlob := .F.
      cIns += cPreText
---
      cIns := STRTRAN( cIns, CHR( 0 ), " " )    // if any CHR(0)

      nBatch += LEN( cIns )
      IF nBatch >= (nBatchSize*8)              // send when reach half size of Server Cache
         nBatch := 0

         oPG:exec( cIns )                       // now send Query
---
      ELSE
         // EOL
         cIns += ";" + CRLF                     // Add to "one LIne"
      ENDIF
greeting,

Jimmy
Posts: 318
Joined: Fri Jan 14, 2022 08:37 AM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 07, 2024 03:01 PM

César, Jimmy,

Lo voy a intentar según el esquema de César atendiendo al límite de bufferización que propone Jimmy

Gracias a ambos

Posts: 111
Joined: Sun Oct 09, 2005 03:09 PM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 07, 2024 06:56 PM

Buenas tardes desde Puebla Mexico, yo tuve esa problematica y la resolvi utilizando el metodo SetAutoCommit( lOnOff) del objecto Connection (oCon)

primero antes de iniciar los insert lo pongo desactivado

oCon:SetAutoCommit(.f.)

y al terminar todas las inserciones lo regreso a activado

oCon:SetAutoCommit(.t.)

En el ejemplo oCon es el nombre de tu objeto connection.

Saludos

Saludos

Atentamente

Jose F Dominguez Serafin

email admsoporte@gmail.com
Posts: 318
Joined: Fri Jan 14, 2022 08:37 AM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 07, 2024 07:41 PM

Gracias admSoporte por la respuesta.

Lamentablemente no puedo hacerlo porque uso TDolphin y parece ser, si no estoy equivocado, que no tiene esa posibilidad

BTW. ¿ No haría falta un oConn:Commit() ?

Salu2

Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 21, 2024 09:27 AM

Hola Paquito!

Si quieres velocidad, olvídate de las transacciones. Solo se justifica si la concurrencia es mucha y realmente hay procesos que actualicen simultáneamente la misma tabla.

Haz la prueba: Intala el MySqlWorkbech, tiene un apartado en administración que mide las queries y fíjate lo que pesa un start transaction y un commit.

Un saludo,

Carlos

Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Posts: 302
Joined: Fri Apr 23, 2010 04:30 AM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 21, 2024 02:25 PM

Hola,

Puedes armar la senctencia insert como script y usar Execute de tdolphin y te funciona de maravillas, si lo haces registro a registro se realiza un bloqueo a nivel de tabla por cada insert.

Slds,

Nicanor

Nicanor Martinez M.
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
Posts: 318
Joined: Fri Jan 14, 2022 08:37 AM
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 21, 2024 03:50 PM
Carlos Mora wrote:Hola Paquito!

Si quieres velocidad, olvídate de las transacciones. Solo se justifica si la concurrencia es mucha y realmente hay procesos que actualicen simultáneamente la misma tabla.
Haz la prueba: Intala el MySqlWorkbech, tiene un apartado en administración que mide las queries y fíjate lo que pesa un start transaction y un commit.

Un saludo,

Carlos
Hola Carlos,

Qué sorpresa tan agradable verte por aquí. Tu estupendas soluciones aun son consultables en el foro y cuanto nos ayudan a muchos !!
Gracias por tu interés. Digo lo que he hecho más abajo

nnicanor wrote:Hola,

Puedes armar la senctencia insert como script y usar Execute de tdolphin y te funciona de maravillas, si lo haces registro a registro se realiza un bloqueo a nivel de tabla por cada insert.

Slds,Nicanor
Hola nnicanor,

Gracias por tu interes. Debajo pongo la solución que he usado:

La solución que he usado ha sido usar el comando "LOAD DATA LOCAL INFILE" que me ha acelerado mucho las subidas de informacion.
Lo probé poniendo transacciones grandes, luego pequeñas, luego más pequeñas y nada, no mejoraba.
En cambio con LOAD DATA LOCAL INFILE, despues de habilitar permisos en el servidor para que permita ese comando, ya si arreó como una moto

Gracias a TODOS los que habeis tomado interés en el hilo.

Continue the discussion