Profile

Cover photo
David Giordano
Works at Kidbox
Lives in Montevideo
280 followers|26,141 views
AboutPostsPhotosYouTube

Stream

David Giordano

commented on a post on Blogger.
Shared publicly  - 
Tengo una tabla Log con 1.000.000 de registros En la tabla hay 100.123 registros de los últimos treinta días y necesito actualizarlos. Para eso pruebo los siguientes procedimientos, que tienen codigo equivalente, pues solo ...
1
Enrique Almeida's profile photoDavid Giordano's profile photo
2 comments
 
+Enrique Almeida Para mi es lo mismo, uso de funciones u operaciones en el where y como se optimizan las sentencias por parte de GeneXus, la única diferencia es que uno es aplicado para un select y otro es para un update, pero la regla general es la misma.

Faltó que hicieras este ejemplo (seguramente va a dar en el mismo orden de magnitud que el mejor caso, en una de esas no)

&FltServerDate = ServerDate() - 30
For Each
Where LogDate > &FltServerDate
       LogObservation = 'YYY'
EndFor

Otro ejemplo (asumiendo que los LogId son sencuenciales)

&FltServerDate = ServerDate() - 30
For Each
Where LogDate > &FltServerDate
       &FltLogId = LogId
      Exit
EndFor

For Each
Where LogId >= &FltLogId
       LogObservation = 'YYY'
EndFor

Usar &serverdate lo que ayuda es que se precalcula ese valor, en el caso de uso de serverdate() ese valor se evalúa en el bucle de todos los registros uno a uno llamando además a la función serverdate para restarle 30 y evaluar esa condición y luego ejecuta el update.
Caso &Serverdate, se resuelve en una sentencia Update, por lo que se evalúa todo dentro de la base de datos y no hay tráfico entre base de datos y aplicación, el caso de serverdate() todos los registros se seleccionan y se transfieren por red, emitiendo un update por cada uno (y no se si en algunos casos no hace primero un select for update para bloquearlo).

Y este otro ejemplo

&FltServerDate = ServerDate() - 30
For Each
Where LogDate > &FltServerDate
       &LogId = LogId
       Do 'Modif Registro'
EndFor

Do 'Modificar Registro'
     For Each
     Where LogId = &LogId
            LogObservation = 'YYY'
     EndFor
     commit // lo antes posible
End

Bueno, el ejemplo de la optimización de hacerlo solo con un gran update, lo que puede ocasionar es "golpecito" en la base de datos y un bloqueo en muchos registros para el update durante ese segundo. Si estás con alto uso en la base de datos y además con alta concurrencia por select o modificación sobre esa tabla (parece ser un log, seguramente cualquier cosa vaya para ahí), eso puede ocasionar una guerra, no necesariamente lo rápido es mejor (si te demora 1 segundo, pinta que es SQLServer, me gustaría ver un DB2400 como se comporta).
En el segundo caso, el uso de ServerDate() tendría que ver las sentencias generadas, pero si hace un select for update, ya está reservando el registro para ser modificado con lo que en realidad hasta que no termine y se haga commit van a estar bloqueados los registros (según tu ejemplo, posiblemente 186 segundos, peligroso, puede generar un bloqueo y encolados por updates importante).

El segundo ejemplo que pasé, simula un select no para update, pero ejecuta registro a registro un update, bloqueando solo ese registro cuando se quiere modificar, el hecho que tenga un commit además ayuda a liberar lo antes posible y tener un transacction log mas pequeño (cuando las modificaciones son masivas, hacer update masivos para el dbms es todo un problema, tiene que estar bloqueando y preparado para hacer un rollback de todos los cambios sin commit).
Claro que el ejemplo asume cosas, asume que hay competencia por update, seguramente es mas lento (posiblemente mas rápido que tu peor caso porque el select es optimo) y transfiere más datos porque viajan los logid para luego modificarse uno a uno, pero en ese ejemplo compite menos y aunque es más lento ayuda a que existan menos bloqueos largos.

Otro caso, es que estás procesando un log histórico, se recomienda procesar de a tandas de X miles de registros, ya que como mencione anteriormente, hay un costo alto del dbms de "marcar" y manteer el rollback en el transaction log.
100 mil registros es poco, pero si esa tabla sigue creciendo en volumen diario, lo que se tiene que buscar es particionar y hacerlo por tandas.
En tu ejemplo es procesar los últimos 30 días, si por día pasaras a tener 100mil registros y para procesar 100mil registros te demora 1 segundo, te demoraría 30 segundos procesarlo todo, pero en una de esas llegas y notas que estás poniendo en límite a la base de datos con un update tan masivo, para ese caso, procesa día a día haciendo un bucle y "comiteando" en cada iteración para liberar a la base de datos del stress del transaction log (y tienes bloqueos mas pequeños). Puedes seguir el ejemplo de obtener el LogId e ir iterando de a rangos hasta no encontrar registros a procesar (asumiendo LogId tiene correlación de secuencialidad con la fecha).

Seguramente en un AS400 (u Oracle) procesar 100mil registros de un golpe como lo estás realizando pueda dar problemas (cada dbms tiene su forma de manejar sus bloqueos y el transaction log).

Me encantan Enrique tus post de Pienso Pienso. :)




 
 ·  Translate
Add a comment...
Have him in circles
280 people
Sebastián Martínez's profile photo
Maria Jose Serres's profile photo
Diego Ocampo's profile photo
Cinthia Soca's profile photo
Jorge Juan Mastropietro's profile photo
Marcos Begerez's profile photo

David Giordano

Shared publicly  - 
 
Risk-Based Testing: Test Only What Matters http://feedly.com/e/btL5HQlf
1
Add a comment...
 
Google lanza cinco minijuegos para Google Glass http://feedly.com/e/XNKaitOp
 ·  Translate
3
Add a comment...

David Giordano

Shared publicly  - 
 
This is probably the funniest table tennis match you’ll ever watch http://feedly.com/e/j77dJ5kb
1
Add a comment...
People
Have him in circles
280 people
Sebastián Martínez's profile photo
Maria Jose Serres's profile photo
Diego Ocampo's profile photo
Cinthia Soca's profile photo
Jorge Juan Mastropietro's profile photo
Marcos Begerez's profile photo
Work
Occupation
Programador
Employment
  • Kidbox
    CTO, 2011 - present
  • de Larrobla & Asociados
    Programador, 2001 - 2011
  • Departamento de informática CGE
    Programador, 1999 - 2001
Basic Information
Gender
Male
Other names
3dgiordano