DAX

Tablas Expandidas en Power BI

Como muchos de los que me leéis ya sabéis, dentro de una semana arrancan los Power BI Days de Santiago de Compostela. Un evento espectacular que lleva el conocimiento en Power BI y Fabric de manera altruista por toda la geografía española. Y, ya con la vista puesta en el evento que, por supuesto, no me voy a perder, estaba pensando en la anterior edición. En ella, pude asistir, entre otras, a una magistral charla de Ricardo Rincón y Miguel Egea sobre las tablas expandidas en Power BI. Y, pensando en esto, me he acordado de que yo no os he hablado a vosotros de este concepto. 

El concepto de tablas expandidas en Power BI es fundamental para entender cómo funcionan cosas tan básicas como las relaciones entre tablas y la propagación de filtros. Las tablas expandidas permiten que Power BI maneje automáticamente la interacción entre múltiples tablas relacionadas, facilitando la creación de informes y cálculos avanzados sin necesidad de escribir complejas consultas. En este artículo, vamos a intentar ver en detalle qué son las tablas expandidas, cómo funcionan y cómo pueden aprovecharse para optimizar modelos de datos en Power BI. 

¿Qué son las tablas expandidas?

Las tablas expandidas en Power BI son una representación lógica que se crea a partir de las relaciones establecidas entre las tablas de un modelo de datos. Cuando las tablas están relacionadas a través de relaciones de muchos a uno o uno a uno, Power BI trata esas tablas como si fueran una sola entidad expandida. Esto permite que los filtros y los cálculos se propaguen automáticamente a través de esas tablas relacionadas, sin necesidad de que el usuario intervenga directamente en la relación, es decir, sin tener que hacer un join como hacemos en SQL.

Imaginad un modelo de datos simple donde tenemos una tabla de Ventas, una tabla de Productos y una tabla de Categorías. La relación entre estas tablas nos permite que, al aplicar un filtro a la tabla de Categorías, los datos correspondientes en las tablas de Productos y Ventas se actualicen automáticamente, gracias al uso de las tablas expandidas.

Este comportamiento es clave para simplificar el análisis de datos en Power BI, ya que elimina la necesidad de realizar operaciones manuales para combinar datos de diferentes tablas. Las tablas expandidas también permiten que los cálculos en DAX (Data Analysis Expressions) se apliquen de manera automática a través de múltiples tablas relacionadas.

¿Cómo funcionan las tablas expandidas?

El funcionamiento de las tablas expandidas depende de las relaciones que existen en el modelo de datos. En Power BI, las relaciones de uno a muchos y uno a uno son las que permiten la propagación de filtros. Esto es importante pues como ves no estoy incluyendo aquí las relaciones muchos a muchos. Cuando se crea una relación de muchos a uno entre dos tablas, Power BI automáticamente añade (de manera lógica) todos los campos de la tabla del lado del 1 en la del lado del mucho de manera que internamente trabaja como una sola tabla expandida. Sin embargo, cuando las relaciones son 1:1 todos los campos de las tablas se propaga a la otra, y viceversa.

Por ejemplo, si tenemos una tabla de Productos y una tabla de Ventas, con una relación entre ambas basada en el ID del Producto, cualquier filtro que apliquemos en la tabla de Productos se reflejará automáticamente en los datos de la tabla de Ventas. Esto es posible gracias a las tablas expandidas, que permiten que Power BI combine virtualmente las dos tablas en una sola.

Este comportamiento no solo se aplica a la visualización de datos, sino también a los cálculos realizados con DAX. Al usar medidas que involucran tablas relacionadas, Power BI toma en cuenta automáticamente las tablas expandidas, lo que facilita la creación de cálculos complejos sin necesidad de realizar combinaciones manuales de datos.

Propagación de filtros y relaciones

Una de las principales ventajas de las tablas expandidas es su capacidad para manejar automáticamente la propagación de filtros entre tablas. Cuando aplicamos un filtro en una tabla que está relacionada con otras, Power BI propaga el filtro a través de las relaciones, afectando las tablas relacionadas sin que sea necesario especificarlo explícitamente en el código.

Por ejemplo, en un modelo de datos con las tablas Ventas, Productos y Categorías, si aplicamos un filtro en la tabla Categorías (como seleccionar solo productos de la categoría «Electrónica»), Power BI propagará automáticamente ese filtro a las tablas Productos y Ventas. Esto significa que cualquier visualización o cálculo basado en las tablas Productos o Ventas reflejará solo los datos relacionados con la categoría «Electrónica», sin necesidad de que el usuario especifique esa relación en cada consulta.

Como ves, esto simplifica enormemente la creación de informes y análisis, ya que los usuarios no necesitan preocuparse por cómo se combinan los datos de diferentes tablas, Power BI lo maneja automáticamente a través de las tablas expandidas.

Uso de DAX y las tablas expandidas

El lenguaje DAX en Power BI aprovecha al máximo el concepto de tablas expandidas para realizar cálculos avanzados. Al crear medidas en DAX, Power BI utiliza automáticamente las tablas expandidas para propagar los cálculos a través de las tablas relacionadas. Esto permite simplificar los cálculos, ya que no es necesario especificar las combinaciones manuales entre tablas.

Veamos un ejemplo práctico utilizando DAX. Imaginemos que queremos calcular el total de ventas por categoría de producto, usando las tablas Ventas, Productos y Categorías mencionadas anteriormente. Gracias a las tablas expandidas, podemos escribir una medida que se aplique automáticamente a todas las tablas relacionadas.

Ejemplos prácticos de tablas expandidas en Power BI

Para comprender mejor cómo las tablas expandidas simplifican el análisis en Power BI, os he preparado varios ejemplos prácticos.

Estructura de las tablas

Tabla Ventas:

ID Venta ID ProductoCantidad Precio Total
1P001 10100
2P002550
3P003 880

Tabla Productos:

ID ProductoNombre Producto ID Categoría
P001 TelevisorC001
P002Lavadora C002
P003Microondas C001

Tabla Categorías:

ID Categoría Nombre Categoría
C001Electrónica
C002Electrodomésticos

Ejemplo 1: Total de ventas por categoría

En este ejemplo, queremos calcular el total de ventas por categoría. Gracias a las tablas expandidas, podemos hacerlo sin tener que realizar combinaciones explícitas entre las tablas Ventas y Categorías.

Medida DAX:

Total Ventas por Categoría = 

Explicación:

La medida recorre la tabla de Productos y, para cada producto, calcula la suma del Precio Total de las ventas asociadas. Power BI expande automáticamente la tabla de Productos para incluir los datos de Ventas y Categorías, aplicando los filtros correspondientes.

Resultado esperado:

Nombre Categoría Total Ventas
Electrónica 180
Electrodomésticos 50

Ejemplo 2: Filtrar por categoría

Queremos calcular las ventas totales solo para productos de la categoría «Electrónica». Nuevamente, Power BI manejará automáticamente la propagación del filtro a través de las tablas expandidas.

Medida DAX:

Total Ventas Electrónica = 

 Resultado esperado:

Ejemplo 3: Visualización con tablas expandidas

Podemos crear una visualización que muestre las ventas por producto y categoría. Gracias a las tablas expandidas, no necesitamos incluir manualmente todas las tablas en la visualización.

 Visualización:

Utilizamos las columnas Nombre Categoría de Categorías, Nombre Producto de Productos y el Precio Total de Ventas.

 Resultado esperado:

Implicaciones de rendimiento

Aunque las tablas expandidas simplifican el modelado de datos, es importante ser conscientes de su impacto en el rendimiento. A medida que creamos más relaciones y tablas expandidas, el modelo de datos puede volverse más complejo, lo que puede afectar al tiempo de respuesta en las consultas y visualizaciones.

Para mitigar este impacto, es recomendable optimizar las relaciones y el tamaño de las tablas. Evitar tablas innecesariamente grandes o relaciones que no sean estrictamente necesarias puede ayudar a mantener el rendimiento del modelo bajo control.

Conclusión

Las tablas expandidas son una herramienta poderosa en Power BI que permite simplificar el análisis de datos a través de la propagación automática de filtros y la integración de datos entre múltiples tablas relacionadas. Al utilizar tablas expandidas, los usuarios pueden crear modelos de datos más eficientes y realizar cálculos complejos con menor esfuerzo.

Sin embargo, si queremos ir más allá, es crucial que seamos conscientes de las implicaciones de rendimiento y que diseñemos modelos optimizados que aprovechen al máximo las capacidades de Power BI sin comprometer la eficiencia. Con el uso adecuado de las tablas expandidas, podemos crear modelos de datos robustos que permitan un análisis rápido y preciso.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Power BI, Rendimiento, 0 comentarios

SQL vs DAX ¿Quién es más rápido?

El pasado viernes andaba yo absorto en la masterclass de Salvador Ramos en Nasmasdata cuando, de repente, una diapositiva salvaje apareció. Salva nos hablaba de un cálculo de stock acumulado con su fórmula en DAX porque según ponía en SQL era un cálculo imposible. ¿IMPOSIBLE? Eso era un reto para mí, así que, raudo tomé una captura de pantalla y acepté ese reto. No hubo que esperar mucho, hoy sábado, de buena mañana me he sentado delante del ordenador, he creado una tabla con los datos necesarios para la prueba y me he puesto manos a la obra. No sin antes contactar a Salva e informarle de lo que estaba aconteciendo porque sí amigos, Salva sabe de la existencia de este artículo días antes que vosotros, para la próxima que el reto venga de vosotros y estaréis informados antes. 

SQL-vs-DAX_1

Entendiendo el reto en DAX

Lo primero que tenemos que entender es lo que nos propone el reto, la medida DAX que se ve en la imagen es esta:

Por un lado CALCULATE es una función que cambia una expresión en un contexto de filtro modificado. Como parámetros le hemos pasado [Stock Final] que es una medida o una calculada que nos sumariza los movimientos de stock. Para el segundo parámetro hemos pasado la función FILTER con dos parámetros más, el resultado es que filtra la tabla Fecha para incluir solo las filas donde la fecha es menor o igual a la fecha máxima en el contexto actual.

Convirtiendo el DAX a T-SQL

Ahora que ya sabemos lo que tenemos que obtener vamos a ver como debemos hacerlo en SQL Server, a ver si realmente era imposible o no. He de deciros que mi tabla solo tiene dos columnas fecha y stock. Podriamos haber complicado el escenario añadiendo artículos pero para la demo nos vale sin eso, supongamos que tenemos solo uno. Como luego vamos a llevarnos estas tablas a Power BI tal como están en SQL no hay problema, en DAX vamos a jugar en las mismas condiciones.

Para empezar vamos a tener que totalizar por dias para saber cuantos movimientos hemos tenido ese día. Luego tenemos que hacer una suma de los valores desde la primera fecha hasta la fecha actual. Eso lo podremos lograr con una función de ventana. Esta sería la consulta imposible:

Vamos a verla paso a paso. En lo primero que nos tenemos que fijar es en la subconsulta del FROM. Es justo lo que comentábamos antes, la suma de los movimientos de stock agrupados por día. Luego, en la consulta principal, estamos utilizando una función de ventana para calcular el Stock_Acumulado. Esta función de ventana SUM() OVER (ORDER BY Fecha ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) suma los valores de Stock_Final en todas las filas desde el inicio de la tabla (UNBOUNDED PRECEDING) hasta la fila actual (CURRENT ROW), ordenadas por Fecha. Esto da como resultado un total acumulativo de Stock_Final hasta la fecha actual.

SQL-vs-DAX_2

Ya lo tenemos, no era imposible. Sin embargo, a lo que Salva se refería era los inconvenientes de realizar los cálculos en SQL por tiempos. Y realmente este es un pensamiento muy extendido en el sector. DAX es más rápido realizando cálculos que SQL Server. Pero, ¿realmente es cierto? Vamos a verlo.

Comparativas de rendimiento DAX vs SQL

Para que los resultados puedan ser representativos, vamos a hacer las pruebas sobre una tabla con algo más de 1 millón de registros, algo normal en una empresa pequeña. Vamos a analizar dos años de datos de movimientos de stock. Para medir los tiempos de la consulta DAX he sacado la consulta de la tabla y la he llevado a DAX Studio. En SQL vamos a usar las estadísticas de tiempo que podemos sacar con SET STATISTICS TIME ON.

SQL-vs-DAX_3

Como vemos los resultados son demoledores y para nada lo esperado. Analizando 1.010.000 registros repartidos en 1096 fechas distintas SQL Server se ha demorado 85 milisegundos de los cuales 78 ms han sido CPU. En DAX Studio podemos ver que la fórmula DAX para la tabla ha tardado 180 milisegundos, repartidos entre 175 ms del motor de fórmulas (FE) y 5 ms del motor de almacenamiento (SE). 

Complicando el escenario

Vamos a pasar de 1 millón a 15 millones de registros a ver si los resultados son distintos. Todos sabemos que el fuerte de Power BI reside en su motor Vertipaq y su gran capacidad de trabajar con grandes cantidades de datos.

SQL-vs-DAX_4

Ahora sí que vemos la gran diferencia de tiempos de la que todo el mundo habla en DAX y Power BI. Con 15 millones de registros los tiempos en SQL Server se han disparado a 1219 milisegundos de CPU aunque paralelizando la consulta se ha resulto en 186 ms. En DAX tenemos un tiempo total de 193 milisegundos repartidos en 175 ms del motor de fórmulas (FE) y 18 ms del motor de almacenamiento (SE). Aunque los tiempos de DAX son mayores a los de SQL no hay tanta diferencia y teniendo en cuenta el paralelismo de SQL podemos deducir un mayor consumo de recursos si ejecutamos los cálculos en origen.

Mejorando los tiempos de SQL

Ya sabemos el objetivo a batir en DAX 193 ms. Veamos qué podemos hacer en SQL. Para empezar vamos a probar con un índice columnar sobre la tabla, al fin y al cabo los índices columnares son la misma tecnología que el motor vertipaq de Power BI.

SQL-vs-DAX_5

Ahí lo tenemos, ahora sí. Nuestra consulta sobre la tabla con índices columnares ha tardado 155 milisegundos de CPU y solo 56 ms totales al paralelizar. Aun así esto todavía se puede mejorar, ¿recordáis las vistas indexadas? Vamos a probarlo.

SQL-vs-DAX_6

¿Qué os parece el resultado? ¿Os lo esperabais? Con la combinación de índice columnar más vista indexada hemos podido ejecutar la consulta pesada sobre 15 millones de registros en menos de un milisegundo. A mi me ha sorprendido la verdad. No esperaba tanta mejoría.

Es importante destacar que esto es una prueba de concepto en un entorno de laboratorio sin carga de trabajo donde puedo hacer todos los cambios que quiero sobre el SQL sin afectar a ningún otro proceso. Esto es un escenario muy simplificado para la DEMO sin ningún parecido con una base de datos de un ERP de producción. Como siempre digo, primero válida en tus servidores de pruebas y luego, si ves que va bien y no da problemas, piensa en aplicarlo en producción.

Conclusión

SQL sigue más vivo que nunca. Es verdad que DAX es muy potente y seguro que tiene un montón más de optimizaciones de las que yo he sido capaz de aplicar. Os diré que para las pruebas estaba la inteligencia de tiempos desactivada y como dimensión de tiempos estaba usando la plantilla que Salva proporciona gratuitamente en su web que entiendo que es la que usa él. 

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

PD.: Salva, no me importa el resultado de estas pruebas, tu sigues siendo un referente para mi 🙂.

Publicado por Roberto Carrancio en Cloud, Power BI, Rendimiento, SQL Server, 0 comentarios