PiensoPienso: Cual tiene mejor performance?

Tengo una tabla de Registros de Auditoria que tiene unos 10 millones de registros y hay unos 1.000 usuarios diferentes distribuidos mas o menos uniformemente. 

AuditoriaId*   //Autonumber
AuditoriaFechaHora   //Se carga siempre con ServerNow()
AuditoriaUsuario   //Tiene el usuario que realizo el cambio
AuditoriaSistema  //Codigo del sistema
AuditoriaObservacion //Texto con observacion

Cual de los siguientes programas tiene mejor performance: 



1) 
for each (AuditoriaId)
     Where AuditoriaUsuario=UserId()

print AuditoriaObservacio
endfor

2) 
&Usuario=UserId()
for each (AuditoriaId)
   Where AuditoriaUsuario=&Usuario
    
print AuditoriaObservacion
endfor

3) 
for each AuditoriaFecha,AuditoriaUsuario
   Where AuditoriaUsuario=UserId()
      
       print AuditoriaObservacion
endfor

4) 
for each

    If AuditoriaUsuario=UserId()
print AuditoriaObservacion
    Endif

endfor

Se pueden crear todos los indices/estadisticas que se deseen. Justifique su respuesta. 

Comentarios

  1. Parece claro que el indice que se debería usar debería tener si o si el id de usuario. Agregarle la fecha sería simplemente para mostrar en forma prolija la información.
    En el where también parece claro que lo mejor es colocar una variable y no algun tipo de funcion o similar, por lo que estaríamos en:

    &Usuario = UserID()
    For Each AuditoriaUsuario, AuditoriaFecha
    Where AuditoriaUsuario = &Usuario

    print AuditoriaObservacion

    EndFor

    Ahora, varias veces SQL genera los índices que a el se le canta, por lo que como tantas veces, sería cuestión de hacer las pruebas empíricas y ver que pasa.

    No se si me gano algo o por el contrario tengo que pagar algo adicional en el asado si le erre como las peras ;)
    Saludos
    ElAndrew

    PD: Nos estaríamos viendo en la joda de fin de año.

    ResponderBorrar
  2. Apoyo AlAndrew.

    Por alguna razón GX se reúsa a optimizar 1) y 3), generando un if adentró del bucle en vez de mandarlo como where. Por lo cual quedan parecidos al 4), éstos quedan descartados porque obliga tanto al DBMS como al programa a recorrer 10 millones de registros. Dejando como ganador a 2).

    ResponderBorrar
  3. Yo concuerdo con lo antes expuesto por el Sr. Andres, pero como la idea es elegir una, me inclino porque la que tendrá mayor preformance será la opción 2) ya que solo se hace la llamada a la función UserId() una vez.

    Creo que en todas las opciones propuestas se tendría que rercorrer toda la tabla, sin importar los indices existentes.

    Saludos.

    PD: Cualquier cosa lo discutimos con un pedazo de asado en el plato y una ceerveza fria en la mano :P

    ResponderBorrar
  4. Diego, en realidad no es necesario recorrer toda la tabla.

    En Genexus estás indicando el orden en que querés ver los resultados, no el índice que tiene que usar, así que el DBMS puede utilizar un índice por {Usuario, Id} para recorrer sólo los registros del usuario filtrado y además ya está ordenado por Id.

    Incluso del U5 de Gx9 detecta estás situaciones y agrega el atributo que está en el where al orden si cree que es más óptimo.

    ResponderBorrar
  5. Andres:
    Tu respuesta es correcta.
    No concuerdo a que las bases de datos creen los indices que se les canta,sino que tiene logica lo que hace. Son algoritmos complejos los optmizadores, pero si se los estudia, se puede entender.

    Pablo:
    En los casos 1), 3) la funcion UserId() no se incluye en el where, por lo que la consulta debe ser resuelta en el cliente, haciendo que queden ambas parecidas a 4) como vos decis.
    Es correcta tu respuesta.

    Diego:
    En la opcion 2, si hay un indice por AuditoriaUsuario, no necestia recorrer toda la tabla. Podria elegir recorrer toda la tabla, si piensa que para ese usuario tiene muchos registros, pero con estadisticas sobre el campo Usuario alcanzaria para que la base de datos sepa que no tiene que hacer un FULL SCAN.

    Una cosa que si me gustaria, es que se mostrara mas claramente en la navegación de Genexus que condicion se resuelve en el servidor y cual se resuelve en el cliente, porque la diferencia en performance puede ser enorme.

    Gracias a todos por los comentarios , intercambios y soluciones.

    A todos los que respondieron, se ganaraon el derecho a escuchar una cancion de Zambayonny ( http://www.myspace.com/zambayonny)

    ResponderBorrar

Publicar un comentario

1) Lee el post
2) Poné tu opinión sobre el mismo.
Todos los comentarios serán leidos y la mayoría son publicados.

Entradas más populares de este blog

Aplicación monolítica o distribuida?

La nefasta influencia del golero de Cacho Bochinche en el fútbol uruguayo

Funcionalidades de GeneXus que vale la pena conocer: DATE Constants.