Page 1 of 1
Velocidad al grabar multiples registros en Mysql
Posted: Tue Aug 06, 2024 11:17 am
by paquitohm
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
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
Re: Velocidad al grabar multiples registros en Mysql
Posted: Tue Aug 06, 2024 12:16 pm
by cmsoft
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
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
oServer:InsertFromDbf( cTable, cAlias, nLimit, aStruct, bOnInsert, cDuplicateKey, bOnRow )
Seguramente la clase nativa tiene algo similar
https://forums.fivetechsupport.com/view ... =3&t=32657
Espero te sirva de base para tu caso
Re: Velocidad al grabar multiples registros en Mysql
Posted: Tue Aug 06, 2024 12:40 pm
by Jimmy
hi,
you speedup a lot when send multiple INSERT Commands in "one line", depend on Cache Configuration of SQL-Server
Code: Select all | Expand
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
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 07, 2024 3:01 pm
by paquitohm
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
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 07, 2024 6:56 pm
by admsoporte
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
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 07, 2024 7:41 pm
by paquitohm
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
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 21, 2024 9:27 am
by Carlos Mora
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
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 21, 2024 2:25 pm
by nnicanor
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
Re: Velocidad al grabar multiples registros en Mysql
Posted: Wed Aug 21, 2024 3:50 pm
by paquitohm
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.