sábado, diciembre 05, 2015

Profundizando en los FlowFields

Para mí una de las funcionalidades de la plataforma NAV más útil son los FlowFields. Son fáciles de construir, rápidos de ejecutar, exactos en cuanto al resultado, seguros en cuanto a las transacciones y funcionalmente potentes.

Vamos a ver en detalle como NAV conjuntamente con SQL utilizan esta tecnología.

Creación de un FlowField

Para ello vamos a crear una tabla en la que anotaremos los rappels que otorgamos a los clientes de forma periódica por haber alcanzado un determinado volumen de ventas o de margen comercial. Omitiremos el proceso de cálculo y nos centraremos sólo en la tabla.

Diseño de la tabla:


















Veámosla en SQL:










Y ahora añadimos el FlowField correspondiente en la tabla de clientes:



















Veamos que ha sucedido con nuestra tabla de rappels en SQL:










Efectivamente. ¡No ha sucedido nada!
El único índice continua siendo la Primary Key del campo ID.

Entonces ¿que hará NAV y SQL cuando se le pida un listado de, por ejemplo, los clientes 10000 y 30000 con los rappels para el mes de enero de 2017? Pues construir una sentencia SQL parecida a esta:








Está claro que si la tabla de rappels tiene muchos registros, al SQL le costará filtrar los registros por los campos en los que no dispone de ningún índice. (Aunque SQL tiene sus propios trucos, como las estadísticas).

Creación de un SumIndexField

Antes, en versiones anteriores, recuerdo que al crear el campo "Rappel Amount (LCY)" en la tabla de clientes, NAV hubiera obligado a construir un SumIndexField en la tabla "Customer Rappel" para no penalizar el rendimiento.

Pero desde hace algunas versiones esta obligación se ha eliminado, supongo que se confía en que SQL será suficientemente eficiente, ya que SQL incorpora cierto grado de inteligencia para saber qué datos pueden ser optimizados, según la frecuencia y forma de las consultas realizadas.

En nuestro caso, procederemos a crear un SumIndexField en la tabla "Customer Rappel" tal como se indica:


















Veámosla en SQL:











Efectivamente, ahora sí se ha añadido un nuevo índice que contiene los campos "Customer No." y Date. ¿Que hará ahora NAV y SQL cuando se le pida el listado anterior, recordemos, los clientes 10000 y 30000 con los rappels para el mes de enero de 2017?

















Podemos observar como ahora la consulta se ejecutará el doble de rápido al poder aprovechar el nuevo índice e iniciar así 2 procesos en paralelo.

Aunque también deberemos tener en cuenta que si se van a producir muchas alteraciones (altas, bajas, etc.) en esta tabla se va a penalizar el rendimiento de estas operaciones ya que para cada transacción SQL deberá mantener los índices.

Y entonces ¿por qué hemos indicado los campos que se van a calcular en la creación del índice si no han intervenido?

Las SIFT (SumIndexField Tables)

Antiguamente en NAV, al crear un SumIndexField se creaba una tabla en la BBDD con una estructura de combinación de campos y sus correspondientes subtotales.

En nuestro ejemplo anterior, NAV hubiera creado una tabla con los campos "Customer No.", "Date" y "Amount (LCY)". Los 2 primeros porque son los que van a intervenir en los filtros de la consulta y el tercero a modo de subtotal, o sea, 1 solo registro para cada coincidencia en cliente y fecha.

Actualmente estas tablas ya no se crean, en su lugar se crea una consulta indizada, o lo que es lo mismo, una vista junto con un índice.




La utilización de vistas indizadas tiene como ventaja, entre otras, que las agregaciones pueden calcularse previamente y almacenarse en el índice para minimizar los costosos cálculos durante la ejecución de consultas. Además, el optimizador de consultas puede seleccionar la vista si determina que ésta puede sustituirse por parte o por toda la consulta del plan de consultas si es de un coste menor.

Si volvemos al diseño de la tabla y en el SumIndexField accedemos a sus propiedades, aparecerá la siguiente ventana:


Apreciamos como la propiedad MaintainSQLIndex nos indica que sí existe índice en la tabla y como la propiedad MaintainSIFTIndex nos indica que sí existe una vista indizada. Además existen otras propiedades que nos permiten alterar las propiedades del índice directamente en SQL desde NAV.

Como se ha mencionado anteriormente cabe destacar que el rendimiento completo no existe, o primamos las consultas o primamos las modificaciones, pero todo a la vez es imposible. Por tanto en un NAV en producción hay que buscar el equilibrio en cada caso.

Por ejemplo, en una migración o un upgrade, es conveniente desactivar claves o propiedades de los índices con el objetivo de que las altas en la tabla se produzcan los más rápido posible. Posteriormente ya activaremos o no estas propiedades en función del uso que se vaya a hacer (muchas altas o muchas consultas).

Conclusiones

Al crear FlowFields deberemos tener en cuenta que la tabla sobre la que se efectúa el cálculo no se halla optimizada, deberemos hacerlo nosotros.

En dicha optimización NAV utiliza un índice de tabla y una vista indizada, ambos orientados a facilitar el trabajo a SQL siempre que se consultan datos, en nuestro caso, mediante FlowFields.

Si se va a priorizar el rendimiento para las consultas, desde NAV se deberá crear un índice y adicionalmente un SumIndexField, que es el que indica que se va a crear la vista indizada.

Si se van a primar las altas hay que desactivar los índices, ya que éstos se han de actualizar al realizar transacciones en la tabla, a más índices menos rendimiento.

Las propiedades del índice en NAV nos permitirán hacer combinaciones (índice sin vista o vista sin índice).

Es muy recomendable desactivar los índices al realizar migraciones o upgrades ya que en ese momento sabemos de cierto que se van a producir muchísimas altas y pocas consultas.

Más tarde, en fase de producción y tuning, se activarán los índices que procedan.

NOTA: Antes existían los "Database Key Groups" que se utilizaban para activar y desactivar conjuntos de índices, pero ahora están obsoletos.