Condiciones que no se resuelven en el servidor
Cuando se programa en GeneXus, en algunas oportunidades pasa que escribimos condiciones que no son evaluadas en el servidor de base de datos, sino que evalúan en el cliente.
Esto que significa?
Pongamos un ejemplo. Si tengo:
y la base de datos es Oracle, esto va a seleccionar todos los datos de la tabla, y en el cliente (o en el servidor web) va a agregar un IF que seleccione aquellos que tienen FechaHora mayor que la fecha del servidor. Dependiendo de la cantidad de registros que se tenga, eso puede ser muy poco performante.
Como muestra GeneXus este posible problema?
Al costado de la condición muestra un pequeño icono y en el tooltip dice que puede haber problemas de performance.
Esto es suficiente para cuando estoy programando un objeto, pero no lo es cuando estoy realizando migraciones. Con los cambios de versiones, algunas navegaciones cambian y me puede interesar saber cuales son todos los objetos que tienen condiciones evaluadas en el cliente.
La mejor forma (que yo encontré) de identificar cuales son los objetos con condiciones que se evalúan en el cliente es buscar dentro de los directorios NVG de los generadores, en los archivos XML de las navegaciones y encontrar el string "<Icon>client</Icon>"
Resumiendo
Se busca en el directorio GXSPC002\GEN15\NVG, todos los archivos XML que tengan el texto "<Icon>client</Icon>" y eso me da una lista de aquellos objetos que podría mejorarse la performance si logramos cambiar su evaluación al cliente.
Por ejemplo en el caso de arriba, si en vez de poner:
se pone
el programa ya funciona mucho mejor, porque se van a seleccionar menos registros y la diferencia en el tiempo de ejecución puede ser muy grande.
Esto que significa?
Pongamos un ejemplo. Si tengo:
for each where FechaHora > servernow() Msg(FechaHora.ToString()) endfor
y la base de datos es Oracle, esto va a seleccionar todos los datos de la tabla, y en el cliente (o en el servidor web) va a agregar un IF que seleccione aquellos que tienen FechaHora mayor que la fecha del servidor. Dependiendo de la cantidad de registros que se tenga, eso puede ser muy poco performante.
Como muestra GeneXus este posible problema?
Al costado de la condición muestra un pequeño icono y en el tooltip dice que puede haber problemas de performance.
Esto es suficiente para cuando estoy programando un objeto, pero no lo es cuando estoy realizando migraciones. Con los cambios de versiones, algunas navegaciones cambian y me puede interesar saber cuales son todos los objetos que tienen condiciones evaluadas en el cliente.
La mejor forma (que yo encontré) de identificar cuales son los objetos con condiciones que se evalúan en el cliente es buscar dentro de los directorios NVG de los generadores, en los archivos XML de las navegaciones y encontrar el string "<Icon>client</Icon>"
Resumiendo
Se busca en el directorio GXSPC002\GEN15\NVG, todos los archivos XML que tengan el texto "<Icon>client</Icon>" y eso me da una lista de aquellos objetos que podría mejorarse la performance si logramos cambiar su evaluación al cliente.
Por ejemplo en el caso de arriba, si en vez de poner:
for each where FechaHora > servernow() Msg(FechaHora.ToString()) endfor
se pone
&ServerNow = ServerNow() for each where FechaHora > &ServerNow Msg(FechaHora.ToString()) endfor
el programa ya funciona mucho mejor, porque se van a seleccionar menos registros y la diferencia en el tiempo de ejecución puede ser muy grande.
Está bueno el tip, respecto a migración de versiones y comparar navegaciones el "comparador de navegaciones" puede ser útil. Creo que ya lo conoces pero por las dudas: http://wiki.gxtechnical.com/commwiki/servlet/hwikibypageid?3217
ResponderBorrarGusCarr:
BorrarSi, ya lo conocia y lo uso. Es un poco incomodo pero permite identificar objetos que se comportan diferente de una version a la siguente.
Tambien es util, cuando se hace una reorganización grande y se quiere tener controlado cuales son los programas que cambian su navegacion y poder revisarlas en forma detallada.
gracias por el comentario.
Tengo desarrollada una aplicación con Gx Evo 1 (.NET, SQL Server) y la noto muy lenta. No tengo claro por donde empezar para poder encontrar cuellos de botella, etc. Me sirvió tu post para "desayunarme" de estos temas pero con prácticamente el mismo código no me muestra el iconito al que haces referencia... eso es de la Evo 2?
ResponderBorrarTendrás alguna pista por donde puedo empezar a evaluar que "cambiar" para mejorar la performance?
Copio la navegación del objeto al que hago referencia:
Order: FroTipo , FroMenRep , (FroMenFecIni)
! No index
Navigation filters: Start from: FroTipo = TipoForo.Noticia
FroMenRep = 0
Loop while: FroTipo = TipoForo.Noticia
FroMenRep = 0
Constraints: FroMenFecIni <= servernow() and ( FroMenFecFin >= servernow() or FroMenFinPub = 'N')
Join location: Server
=ForoMensaje( FroId, FroMenId)
=Foro( FroId)
~Publicacion( PubId)
~Usuario( FroMenAutUsuCod)