Tras definir nuestro esquema en Estrella en el Data Warehouse, nos topamos con el muro de la realidad. El departamento de dirección tiene un nuevo cuadro de mando (dashboard) conectado directamente a la base de datos SQL. Cuando algún random intentó cruzar "Ventas Totales" por "País" y "Año" de los últimos cinco ejercicios (hablamos de casi 100 millones de registros de tickets), el icono de "Cargando..." se quedó dando vueltas durante 45 segundos.
"Los datos tienen que ser instantáneos", me dijo. Y tenía razón. La solución no pasa por optimizar índices en el motor relacional; hemos llegado al límite físico de lo que un disco duro puede leer bajo demanda. La solución es rendirse a los Cubos OLAP.
El concepto: Pre-calcular el universo
Imagina un cubo de Rubik. En el eje X tienes el Tiempo (Año, Mes, Día), en el eje Y la Geografía (País, Ciudad) y en el eje Z el Producto (Categoría, Marca). En la intersección de esos ejes, hay un número: el importe de las ventas.
La genialidad de los sistemas MOLAP (Multidimensional Online Analytical Processing) como SQL Server Analysis Services es que no calculan la suma cuando tú la pides. La calculan de madrugada.
Durante la ventana de mantenimiento nocturna, ejecutamos un proceso que barre toda la tabla de hechos relacional. El motor de Analysis Services empieza a sumar todas las combinaciones posibles: suma las ventas por año, por mes, por país, por marca, y las combinaciones de todas ellas. Genera unos ficheros binarios altamente comprimidos con estos resultados precalculados.
Sintaxis Multidimensional: MDX
Cuando el cuadro de mando lanza la consulta por la mañana, no usa SQL. Usa MDX (Multidimensional Expressions). No busca en registros individuales, simplemente va al "cruce" exactos del cubo donde ya está guardado el número final.
-- Una consulta MDX típica para extraer las ventas de 2011 en Europa
SELECT
{ [Measures].[Importe Total Ventas] } ON COLUMNS,
{ [Geografia].[Region].&[Europa] } ON ROWS
FROM [Cubo_Ventas_Corporativo]
WHERE ( [Tiempo].[Año].&[2011] )
La sintaxis MDX puede parecer un galimatías alienígena para los que venimos de SQL. Aquí no hay FROM a tablas, sino al cubo entero. No cruzamos claves, navegamos por "Jerarquías" y "Miembros".
El resultado es que, ya sea pidiendo el total de un día concreto o el acumulado de toda la historia de la empresa, la respuesta tarda milisegundos. El número ya estaba calculado esperando a ser leído.
Reflexión: El precio de la latencia
Esta magia de velocidad instantánea tiene un coste muy oscuro: la latencia de los datos. Como las agregaciones tardan horas en precalcularse (el famoso "procesado del cubo"), los datos que ven los directores tienen siempre, en el mejor de los casos, un día de retraso (datos a cierre de ayer).
Para entornos financieros puros esto es suficiente, pero los equipos de marketing cada vez exigen ver el impacto de sus campañas "en tiempo real". Nos encontramos en una encrucijada técnica. O asumes tiempos de carga lentos atacando directamente al relacional (ROLAP), o asumes datos del día anterior con un cubo (MOLAP).