Optimización

Optimización de  los tiempos de carga de los  Modelos Multidimensionales

Para optimizar los tiempos de carga con el builder ver este otro HowTo 

Optimización de la apertura de Modelos Multidimensionales

Este how-to se orienta a brindar información sobre la optimización de modelos multidimensionales para lograr mejor performance en las consultas realizadas por los usuarios y en particular a la gestión de redundancia.

Cómo se mantiene la información en el cubo

O3 mantiene la información "agregada" por el último nivel de cada dimensión.
Veamos con un ejemplo que significa esto exactamente. Supongamos que se tiene un cubo con 3 dimensiones Fecha, Producto y Lugar, tal que cada una cuenta con los siguientes niveles de dimensión:
Fecha: Fecha, Año, Mes, Día
Producto: Producto, Familia, Código
Lugar: Lugar, País, Zona, Ciudad

En este caso O3 mantiene la información agregada según los niveles de dimensión Día, Código y Ciudad. Es decir que ante la consulta ¿cuánto se vendió el día 23/mar/2003 del producto con código "zapato0034" en la ciudad de "Montevideo"? O3 responde sin hacer ningún tipo de trabajo extra de agregación, se puede decir que responde en un solo paso y solo con el esfuerzo de recuperar del cubo esa información ya disponible.

En cambio, ante la consulta ¿cuánto se vendió el día 23/mar/2003 de los productos de la familia "prendas de vestir" en la ciudad de "Montevideo"?, O3 debe recuperar del cubo todas y cada una de la ventas realizadas el día 23/marzo/2003 de los productos pertenecientes a la familia "prendas de vestir" en esa ciudad y luego agregarlas (hacer la suma) para obtener el resultado.

Algo de terminología

En el primer ejemplo se dice que O3 resolvió una consulta a nivel [Día,Codigo,Ciudad] (un niveles un vector de niveles de dimensión) utilizando la información ya agregada a nivel [Día,Código,Ciudad], es decir que utilizó información al mismo nivel de agregación, de ahí que la resolvió sin hacer agregación extra.

En el segundo ejemplo O3 resolvió una consulta de nivel [Día,Familia,Ciudad] utilizando información ya agregada a nivel [Día,Código,Ciudad]. En este caso tuvo que hacer agregación extra porque el nivel de la consulta fue "mayor" ( * ) que el nivel de la información disponible.

( * )Se dice que un nivel [x0,....,xn] es mayor otro nivel [y0,..,yn] si xi >= yi para todo i de 0 a n. En este ejemplo, en la dimensión Producto, el nivel de dimensión Familia es "mayor" ( ** ) que el nivel de dimensión Código.

( ** ) Los niveles de dimensión se numeran desde las hojas hacia la raíz comenzando en cero. Por ejemplo en el caso de la dimensión Producto: Código tiene nivel 0, Familia 1, y Producto 3. Es en ese sentido que el nivel Familia es "mayor" que el nivel Código

¿Qué es la redundancia?

Volviendo a la segunda consulta de ejemplo, supongamos que la cantidad de productos de la familia "prendas de vestir" es del orden de decenas o cientos de miles, y que además el día 23/mar/2003 en Montevideo se efectuaron ventas para todos ellos. Entonces, para responder a la consulta O3 va a recuperar del cubo los cientos de miles de ventas hechas ese día en esa ciudad y las va a sumar para obtener la respuesta. Dependiendo de la potencia de cálculo, la velocidad de disco, etc. la operación puede ser lenta. Si además es una consulta que se realiza con frecuencia, luego O3 va a hacer la agregación cada vez. Entonces sería deseable que O3 mantuviera la información también agregada por el nivel [Día,Familia,Ciudad], así podría responder a esa consulta en un solo paso y en un tiempo casi nulo. O3 puede agregar tal información extra en los cubos, a tal proceso se le llama "agregado de redundancia al cubo". Al nivel[Día,Familia,Ciudad] se le llama nivel de redundancia, y al nivel [Día,Código,Ciudad] se le llama nivel base (de redundancia).

Por defecto todo cubo tiene la información ya agregada por el nivel base.

En el ejemplo el cubo tiene información a nivel [Día,Código,Ciudad] (el nivel base) y a nivel de redundancia [Día,Familia,Ciudad]. Notar que la información agregada según el nivel de redundancia [Día,Familia,Ciudad] es información redundante ya que se puede calcular a partir de la información agregada según el nivel base [Día,Código,Ciudad], de ahí que al proceso se le llame "agregar redundancia". Notar también que el cubo con redundancia debe tener mayor tamaño que el cubo sin ella.

¿Cómo se resuelven las consultas cuando hay niveles de redundancia?

Si se hace una consulta a nivel [Día,Familia,País] (Ej. ventas del día 24/dic/2003 de "prendas de vestir" en China) entonces la consulta se resolverá agregando la información del nivel [Día,Familia,Ciudad] y no del nivel base [Día,Codigo,Ciudad]. Sucede que [Día,Familia,País] >= [Día,Familia,Ciudad] y [Día,Familia, País] >= [Día,Codigo,Ciudad], pero evidentemente se resuelve mas rápido utilizando [Día,Familia,Ciudad]. Sucede que la cantidad de información agregada por [Día,Familia,Ciudad] es menor que la cantidad de información agregada del nivel [Día,Codigo,Ciudad].
En la práctica esto último se puede inspeccionar utilizando Redundancy Manager. RD puede decir cuantas "tuplas" tiene un nivel y cuantas el nivel a partir del cual este se construye.

Veamos este último ejemplo ilustrado con vectores indicando la posición (o altura) de cada nivel en la dimensión. La consulta es a nivel [0,1,2], para resolverla se utiliza el nivel de redundancia [0,1,0] y no el nivel base [0,0,0].

Resumiendo, para resolver una consulta a nivel v se agrega la información del nivel de redundancia w tal que v >= w y w es el mayor nivel que cumple eso.
Además, si v == w entonces la consulta se resuelve sin necesitad de hacer agregación extra.

Un ejemplo que muestra cuando un nivel de redundancia no sirve para resolver una consulta

Supongamos que la consulta es a nivel [2,0,1] (o sea [Año,Código,Zona]), ¿con qué nivel se resuelve? La respuesta es con el nivel [0,0,0], dado que [2,0,1] >= [0,0,0] y no pasa lo mismo con el nivel de redundancia existente [0,1,0] donde la consulta es inferior en la dimensión Producto.
Si la consulta del ejemplo es lenta entonces se puede adicionar otro nivel de redundancia al cubo, por ejemplo [2,0,1], [1,0,1], [1,0,0] o [0,0,1]. El primero logra resolver la consulta en un solo paso pero todos pueden lograr una mejora en el tiempo de resolución.

Algunas observaciones: primero, el cubo tiene ahora 2 niveles de redundancia además del nivel base, así que creció en tamaño, segundo, la cantidad de niveles posibles a adicionar en el caso de que una consulta lo necesite es grande y es muy fácil que se haga una consulta a la cual no le sirve ninguno. De hecho si se quiere que O3 responda a todas las consultas posibles en un solo paso, para un cubo con n dimensiones con
c1,c2... cn niveles se necesitarían c1*c2*...*cn niveles de redundancia. Por ejemplo, un cubo medio con 8 dimensiones de 1,2,3,3,4,3,2 y 2 niveles necesitaría 864 niveles de redundancia, dependiendo del tipo de información del cubo esto podría hacer aumentar el tamaño y tiempo de construcción varias veces.

Conclusiones

El agregado de redundancia es una muy buena solución para mejorar los tiempos de consultas. Pero, adicionar redundancia a un cubo no es tarea simple, al hacerlo se aumenta el tamaño y el tiempo de construcción del cubo.

En general, para lograr una buena mejora en los tiempos se debe:
1- Conocer los datos: sabiendo de antemano qué consultas son las más frecuentes y de ellas cuáles son las más lentas
2- Utilizar la información brindada por los cubos de estadísticas
3- Utilizar Redundancy Manager en forma sistemática para agregar niveles de redundancia, viendo en cada caso cuanto se mejora la relación entre el tamaño de información del nuevo nivel de redundancia y el nivel en el cual éste se apoya, si el nuevo nivel no mejora la relación entonces no se adiciona

Nota: para que la Redundancia tenga sentido se necesita que la mayor cantidad de dimensiones posible tenga por lo menos mas de un nivel de dimensión, solo en ese caso la redundancia tiene un efecto positivo.