Page 1 of 1

Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Mon Jul 23, 2012 2:01 pm
by Adolfo
Holas a todos.

Tengo que hacer una carga masiva de un proceso (generacion de cargos de mantencion de un Tarjeta de credito),
el usuario selecciona la fecha, el monto, la glosa del cargo, y yo a su vez genero un registro en 3 tablas diferentes.

Las cargas pueden ser de hasta 10.000 clientes por cada vez, todo me funciona bien, pero el proceso tomas varios minutos. Hay algun tipo de tip, consejo para "ACELERAR" la generacion de este cargo.

Utilizo Harbour 3, Bcc 5.8, tDolphin, Mysql 5.0.4 en un server Linux, la red esta normada.

Cualquier aydua sera bienvenida.

Desde Chile
Adolfo

Re: Mysql, Tdolphin, Carga Masiva y velocidad

PostPosted: Mon Jul 23, 2012 2:13 pm
by Raymundo Islas M.
Adolfo,

Hace poco tambien tuve que buscar la manera de "acelerar" el proceso de introducir datos y la mejor opcion encontrada fue LOAD DATA INFILE

Ignoro si la clase de Daniel la soporte.

Pero de que fue rapisimo lo fue.

Saludos

Re: Mysql, Tdolphin, Carga Masiva y velocidad

PostPosted: Mon Jul 23, 2012 2:20 pm
by rolando
Raymundo,

¿Que utilizas para manejar MySql?

Gracias.

Rolando :D

Re: Mysql, Tdolphin, Carga Masiva y velocidad

PostPosted: Mon Jul 23, 2012 2:34 pm
by Adolfo
Raymundo

Fijate que me has dado una excelente idea.
Puedo generar el .CSV en forma local y luego cargarlo.

Voy a probar a ver cuanto mejoro la velocidad.
El unico 'pero', puede ser la clave de la tabla, una no es autoincremental.

Grax.

Desde Chile
Adolfo

Re: Mysql, Tdolphin, Carga Masiva y velocidad

PostPosted: Mon Jul 23, 2012 3:23 pm
by Ariel
Adolfo,
como te comenta Raymundo, esa es la opcion mas rapida, y puedes definir que campos incluir, aqui un ejemplo con TDolphin :

Code: Select all  Expand view


// Primero exporto la consulta.
   cFile:= cFilePath( hb_argv(0) )+"TMP\mitemp"+cDateTime+".sql"
   aStrut:= oApp:oCon:TableStructure(cTable)
   FOR x:= 2 TO LEN(aStrut)
// empiezo del campo 2 xq el 1 es autoinc
          w_str+= if(x>2,",","")+aStrut[x,01]
   NEXT
   oQry:= oApp:oCon:Query( [SELECT ]+w_str+[ FROM ]+cTable+[ ORDER BY ]+cTable+[_id] )
   oExp:= oQry:Export( EXP_SQL, cFile )
   oExp:lDropTable:= .f.
   oExp:Start()
   oQry:End()

// Segundo levanto la info exportada.
luego lees el .sql con TTxtFile y ejecutas las sentencias de cada linea

 



Eso es todo , espero te sirva.

Salu2, Ariel

Re: Mysql, Tdolphin, Carga Masiva y velocidad

PostPosted: Mon Jul 23, 2012 10:55 pm
by Raymundo Islas M.
Rolando,

ADO + MySQL

Me ha funcionado muuy bien esta combinacion, no he tenido oportunidad de jugar con otros motores, quizas un poco con MariaDb.
Pero le ando buscando horas al dia para checar Percona y MemSql, este ultimo ya lo instale, solo me falta importar los datos para empezar a probarlo para ver si en verdad hace las cosas con la velocidad que presumen.

Adolfo,
Para agilizar un poco la creacion del archivo txt,cvs,etc puedes crear un query y redirigir la salida a un archivo.

Saludos

Re: Mysql, Tdolphin, Carga Masiva y velocidad

PostPosted: Wed Jul 25, 2012 10:34 pm
by Adolfo
ACTUALIZO mis resultados

Sorprendente.
En una generacion de 10 registros, con todos sus "aliños" se demoraba 9.324 segundos, ahora 1.7
En una generacion de 100 registros, con todos sus "aliños" se demoraba 49.324 segundos, ahora 5.9
Excelente.

Solo genere un CSV asi.

BV; 3455445;2012-07-25; 129876,899, JAVIER; 1;DESPACHO LOCAL ........................................ hasta 35 campos... y al final un CRLF
.............. hasta la cantidad de lineas que necesitaba, solo que la ultima linea no lleva el CRLF.

Ojo Crear el csv con memowrite NO SIRVE. pero con fWrite... ningun problema, es por el caracter de fin de archivo que pone MemoWrite
EL CAMPO PRIMARY KEY no debe ser puesto en el CSV, en mi caso, tengo un Correlativo autoincremental, asi que me funciono, en el caso de Primary Key Compuestas tambien funciona bien.

Luego en una parte de mi programa hago.

Local cSql:="LOAD DATA Local INFILE 'C:\\carga.csv' INTO TABLE mitabla FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n' (Campo1,Campo2,Campox)"

SqlDo(cSql).. y "voila" la magia se hizo.

PD SqlDo(), es una funcion mia para ejecutar sql directamente, pueden usar el oSvr:Execute(cSelect) si usan TDOLPHIN
Gracias por el cable a tierra, hay varias partes del sistema con cargas de hasta 100 registros que ahora voy a "ACELERAR", ojo y con 1 registro es casi igual.

Eso, espero que les sirva mi solucion por si tiene algun cuello de botella por ahi.

Desde Chile
Adolfo

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Thu Jul 26, 2012 3:12 am
by Daniel Garcia-Gil
Hola Adolfo

te dejo un ejemplo usando un poco el "bajo nivel" de TDolphin... actualice este ejemplo en el SVN con el nombre de testuse.prg, aparte hice una pequeña modificacion a la libreria (buen momento para actualizarla)
lo probe en ubuntu 11.04 32 bits
Adolfo wrote:En una generacion de 100 registros, con todos sus "aliños" se demoraba 49.324 segundos, ahora 5.9

en el ejemplo solo demoro 1 seg...
con 1.000 filas registro 4 seg y con 5.000 20 seg (espero sea lo que buscas)
el secreto del ejemplo es usar la funcion mysqluseresult que es mucho mas rapida que mysqlstoreresult (normalmente usada), si te das cuenta existen 2 conexiones (oServer y oServer2) es para poder usar la funcion antes mensionada porque esta obliga a llegar hasta el final de las filas del query para poder ejecutar otra sentencia...

Code: Select all  Expand view
//#include "hbcompat.ch"
#include "tdolphin.ch"
#define CRLF Chr( 13 ) + Chr( 10 )

PROCEDURE Main()
   
   LOCAL oServer   := NIL
   LOCAL cText := ""
   LOCAL oQry
   LOCAL aDatas := {}
   LOCAL hResult, row
   LOCAL aStructure
   LOCAL nLimite := 1000
   LOCAL n := 0
   LOCAL aFields := {}
   LOCAL cTime
   
   IF ( oServer := ConnectTo() ) == NIL
      RETURN
   ENDIF
   IF ( oServer2 := ConnectTo() ) == NIL
      RETURN
   ENDIF
   
   IF ! oServer:lError
      cText += "Connection OK" + CRLF
      cText += "Host: " + oServer:cHost +CRLF
      cText += "Database: " +oServer:cDBName + CRLF    
      ? cText + CRLF
      cText = "SELECT * FROM clientes LIMIT 1000"
      oServer:Execute( "truncate table clientes_copy2" )
      cTime = time()
      IF mysqlquery( oServer:hMySql, cText, Len( cText ) ) == 0
         hResult = mysqluseresult( oServer:hMySql )
         aStructure = MySqlResultStructure( hResult, D_SetCaseSensitive(), D_LogicalValue() )
         for each row in aStructure
            AAdd( aFields, row[ MYSQL_FS_NAME ] )
         next
         hb_ADel( aFields, 1, .T. )                  
         DO WHILE .t.
            aRow = mysqlfetchrow( hResult )
            aRow = hb_ADel( aRow, 1, .T. )
            IF Len( aRow ) == 0
                exit
            ELSE
                AAdd( aDatas, aRow )
                n++
                IF n == nLimite
                   n = 0
                   oServer2:Insert( "clientes_copy2", aFields, aDatas )
                   aDatas = {}
                ENDIF
            ENDIF            
         ENDDO
         IF n != nLimite .AND. n > 0
            oServer:Insert( "clientes_copy2", aFields, aDatas )
         ENDIF                           
         ? "termino en: " + ElapTime( cTime, time() )
      ENDIF
   ENDIF

   oServer:End()

RETURN

#include "connto.prg"

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Thu Jul 26, 2012 3:42 am
by Bayron
Hola Daniel, acabo de bajar tDolphin del SVN y me dio el siguiente error al compilar con xHarbour 1.2.1:

Code: Select all  Expand view
l:\FWH10.2\tDolphin>setenvx
# -----------------------------------------------------------------------
# Building dolphin.lib
#
# C COMPILER    :BCC
# PRG COMPILER  :XHARBOUR
# -----------------------------------------------------------------------
Compiling .\source\prg\tdolpexp.prg
Compiling .\obj\XHARBOUR\BCC\tdolpexp.c
Compiling .\source\prg\tdolpqry.prg
Compiling .\obj\XHARBOUR\BCC\tdolpqry.c
Compiling .\source\prg\tdolpsrv.prg
Compiling .\obj\XHARBOUR\BCC\tdolpsrv.c
Compiling .\source\c\function.c
Compiling .\source\c\gerrapi.c
Compiling .\source\lang\msges.c
win-make: *** [.\obj\XHARBOUR\BCC\msges.obj] Error 1
rm .\obj\XHARBOUR\BCC\tdolpsrv.c .\obj\XHARBOUR\BCC\tdolpqry.c .\obj\XHARBOUR\BCC\tdolpexp.c


Code: Select all  Expand view

# -----------------------------------------------------------------------
# Building dolphin.lib                                            
#                                                                        
# C COMPILER    :BCC                                            
# PRG COMPILER  :XHARBOUR                                          
# -----------------------------------------------------------------------
l:\bcc55\bin\bcc32 -c -D__WIN__ -D__XHARBOUR__ -DHB_LEGACY_TYPES_ON -tWM -Il:\xharbour1.21\include -I.\include -o.\obj\XHARBOUR\BCC\msges.obj .\source\lang\msges.c
Compiling .\source\lang\msges.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
.\source\lang\msges.c:
Error E2451 .\source\lang\msges.c 99: Undefined symbol 'ERR_EMPTYALIAS' in function LoadMsgsES
Error E2040 .\source\lang\msges.c 99: Declaration terminated incorrectly in function LoadMsgsES
Error E2139 .\source\lang\msges.c 99: Declaration missing ; in function LoadMsgsES
Warning W8070 .\source\lang\msges.c 99: Function should return a value in function LoadMsgsES
Warning W8004 .\source\lang\msges.c 99: 'ErrMsg' is assigned a value that is never used in function LoadMsgsES
Error E2190 .\source\lang\msges.c 99: Unexpected }
Error E2040 .\source\lang\msges.c 99: Declaration terminated incorrectly
Error E2190 .\source\lang\msges.c 101: Unexpected }
Error E2190 .\source\lang\msges.c 101: Unexpected }
Error E2293 .\source\lang\msges.c 103: ) expected
Error E2040 .\source\lang\msges.c 105: Declaration terminated incorrectly
Error E2190 .\source\lang\msges.c 106: Unexpected }
*** 10 errors in Compile ***
 

Con Harbour 3.0 compila bien....

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Thu Jul 26, 2012 4:22 pm
by Bayron
Solucionado.... en xHarbour tuve que copiar los archivos include al directorio de xHarbour...

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Fri Jul 27, 2012 12:33 pm
by Adolfo
Daniel....

Pruebo hoy en la tarde y te comento mis resultados.
Saludos

Desde Chile
Adolfo

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Fri Jul 27, 2012 12:56 pm
by Daniel Garcia-Gil
Bayron wrote:Solucionado.... en xHarbour tuve que copiar los archivos include al directorio de xHarbour...


eso quiere deir que tienes mal los path en el script que crea la libreria.. bien que lo solucionante por otra via

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Mon Jul 30, 2012 11:00 pm
by Adolfo
Daniel.

Yo hacia lo siguiente para crear un registro nuevo en TDOLPHIN

Code: Select all  Expand view

oDbNew:=TDNewReg("ciudades","CODIGO")
oDbNew:GetBlankRow(.F.)

oDbNew:CODIGO:=1
oDbNew:Nombre:="CHILLAN"
OdbNew:.......

OdbNew:Save()
 

La funcion TDNewReg, solo crea un qry de 1 solo registro, el ultimo de la tabla,
Code: Select all  Expand view
Function TDNewReg(cTable,cOrder)
Local cSelect:="select * from " + alltrim(cTable) + " order by " + alltrim(cOrder) + " limit 1"
Local oQry:=tDolphinQry():New(cSelect,oSvr)
Return oQry


Algo parecido hacia cuando tenia que crear sucesivos registros en un tabla, como por ejemplo el detalle de ventas de una factura (albaran?)
Un ciclo de 1 al total de productos en el detalle, todo dentro de un loop.

Pero ahora.....
Use el oSvr:Insert("detalle",aCampos,aValores), sin incializar el qry (oDbNew), sino que directamente, y resulto ser aun mas rapido.

Preguntas :
Me interesa saber el porque es mas rapido (curiosidad) ?
Que problema puedo tener al usar ese metodo para mis ciclos de ingreso, me refiero a el oSvr:Insert() ?

Gracias por tu tiempo

Desde Chile
Adolfo

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Tue Jul 31, 2012 12:31 am
by Daniel Garcia-Gil
Hola

Adolfo wrote:Me interesa saber el porque es mas rapido (curiosidad) ?

porque se envia una sola sentencia al servidor, asi el servidor solo compilara una sola setencia
enviar setencias individuales implica generar mas trafico el servidor debe compilar cada una de forma independiente y retornar

un ejemplo visual
para ingresar tres registros en una tabla
oServer:Insert se traduce a
INSER INTO tabla (campo1, campo2, campo3) VALUES (1,2,3),(4,5,6),(7,8,9)

caso contrario a insert individuales

INSER INTO tabla (campo1, campo2, campo3) VALUES (1,2,3)
INSER INTO tabla (campo1, campo2, campo3) VALUES (4,5,6)
INSER INTO tabla (campo1, campo2, campo3) VALUES (7,8,9)

Adolfo wrote:Que problema puedo tener al usar ese metodo para mis ciclos de ingreso, me refiero a el oSvr:Insert() ?

no deberias tener ninguno... yo lo uso de esa forma

Re: Mysql, Tdolphin, Carga Masiva y velocidad SOLUCIONADO !!!

PostPosted: Tue Jul 31, 2012 12:39 am
by Adolfo
Daniel

Clarisima la Explicacion.

Ahora sigo en mis "asuntos" ja ja

Gracias.

Desde Chile
Adolfo