Velocidad al grabar multiples registros en Mysql

Velocidad al grabar multiples registros en Mysql

Postby paquitohm » 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: Select all  Expand view
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
paquitohm
 
Posts: 266
Joined: Fri Jan 14, 2022 8:37 am

Re: Velocidad al grabar multiples registros en Mysql

Postby cmsoft » 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: Select all  Expand view

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: Select all  Expand view
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
User avatar
cmsoft
 
Posts: 1290
Joined: Wed Nov 16, 2005 9:14 pm
Location: Mercedes - Bs As. Argentina

Re: Velocidad al grabar multiples registros en Mysql

Postby Jimmy » 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: Select all  Expand view
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
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: Velocidad al grabar multiples registros en Mysql

Postby paquitohm » Wed Aug 07, 2024 3: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
paquitohm
 
Posts: 266
Joined: Fri Jan 14, 2022 8:37 am

Re: Velocidad al grabar multiples registros en Mysql

Postby admsoporte » Wed Aug 07, 2024 6: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
admsoporte
 
Posts: 103
Joined: Sun Oct 09, 2005 3:09 pm
Location: Mexico

Re: Velocidad al grabar multiples registros en Mysql

Postby paquitohm » Wed Aug 07, 2024 7: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
paquitohm
 
Posts: 266
Joined: Fri Jan 14, 2022 8:37 am

Re: Velocidad al grabar multiples registros en Mysql

Postby Carlos Mora » Wed Aug 21, 2024 9: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"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Velocidad al grabar multiples registros en Mysql

Postby nnicanor » Wed Aug 21, 2024 2: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
nnicanor
 
Posts: 302
Joined: Fri Apr 23, 2010 4:30 am
Location: Colombia

Re: Velocidad al grabar multiples registros en Mysql

Postby paquitohm » Wed Aug 21, 2024 3: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.
paquitohm
 
Posts: 266
Joined: Fri Jan 14, 2022 8:37 am


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 46 guests