¡Otra vez Lunes! ¡Lunes de post! Que mejor manera de comenzar el mes de Agosto que con un post sobre las relaciones virtuales, y en concreto sobre la función TREATAS. Considero que es una función que debemos de tenerla localizada, saber usarla y aplicarla cuando sea necesario, pero sin abusar de ella, y el motivo de por qué no debemos abusar de ella lo iremos viendo según vayamos avanzando en el post.

Según la web de Microsoft, la función TREATAS tiene la siguiente sintaxis:

 

 

Donde:

table_expression es una expresión que da lugar a una tabla.

Column es una o más columnas existentes de nuestro modelo, no puede ser una expresón.

 

TREATAS, aplica el resultado de una expresión de tabla como filtros a las columnas de una tabla no relacionada. ¿Entendido?

Hasta aquí lo más tedioso como digo siempre, y ahora empieza lo divertido, que es entrar en materia con ejemplos prácticos para entender la definición anterior. Vamos como siempre a nuestro modelo de datos de Contoso de Power BI y vamos a partir del mismo ejemplo del post anterior.

Tenemos el siguiente modelo, con 3 tablas de dimensiones conectadas mediante relaciones físicas a nuestra tabla de hechos y una tabla de dimensión desconectada de nuestra tabla de hechos. Hasta aquí, todo igual que en el post anterior.



Y en el informe de Power BI tenemos lo siguiente:

 


 

Donde el segmentador de datos correspondiente al nombre de almacen, corresponde a la tabla de dimensión desconectada DimStore.

 


Y en este caso, la sincronización del segmentador es la siguiente:




Y sólo tenemos en pantalla 2 segmentadores, y no 3 como en el ejemplo anterior, por lo que esta vez no hay ningún truco oculto…

 

 
 
 Por lo que os lanzo una pregunta, ¿si modifico el valor del segmentador del almacen se modificará el valor de las ventas? Como ya me vais conociendo, la pregunta tiene trampa por lo que sí, sí se modificará el valor, mirar:
 

 
 ¿Y cómo es que cambia el valor? Mediante la función TREATAS. Vamos a ver la medida:
 

 
 

Como podemos ver, la sintaxis usada es muy parecida a la usada con USERELATIONSHIP, pero estamos usando la función TREATAS que es la que me permite crear la relación virtual. Si analizamos lo que está haciendo esta función es coger los valores de la columna StoreName de la tabla DimStore, en este caso son los valores que voy seleccionando en el segmentador de datos, y como que “se los traspasa” o filtra por eso valores la columna StoreName de la tabla FactSales. Esto es lo que se conoce como el linaje de los datos. Por eso cuando yo escojo un valor del segmentador de datos, cambia el valor de la medida, aunque entre las dos tablas (DimStore y FactSales) no haya relación.

¿Qué está ocurriendo? Lo primero de todo es que los campos entre los que yo quiero hacer la relación virtual, han de tener valores iguales. Es decir, no puedo poner en uno el nombre del almacén y en el otro las fechas de las ventas, que en ese caso se filtraría, pero nunca encontraría nada. Es lo mismo que para la sincronización de segmentadores que vimos en el post anterior.  ¿Se entiende?

Dicho esto, este es el tercer tipo de relación que podemos tener en DAX. Como hemos podido ver en el modelo, no hay relación física entre las tablas DimStore y FactSales, por lo que, de entrada, va a tener peor rendimiento. Ahora bien, si el escenario en el que nos movemos es con unas tablas con registro de varios cientos, no habría gran problema. Pero si en cambio la volumetría de los registros pasa a millones, pues el rendimiento que obtendremos no será el más óptimo ni mucho menos. Con esto quiero decir que siempre que podamos realizar una relación física, la utilicemos.

¿Tan importante es el tipo de relación que usemos que afecta directamente al rendimiento? Vamos a verlo con el ejemplo actual, para ello vamos hacer un par de modificaciones en nuestro modelo.

Vamos a crear una copia de la tabla DimStore y vamos a crear una relación activa entre la nueva tabla de dimensión y nuestra tabla de hechos FactSales de la siguiente manera:

 

 
 
 
 Tenemos 2 tablas exactamente iguales, pero una con una relación física y otra no. Ahora en nuestro informe, vamos a crear el mismo segmentador de datos con el nombre del almacen, pero de la tabla DimStore (2) y vamos a crear una tarjeta con la medida TotalVentas:

 
 
 

 

Ahora vamos a analizar el rendimiento de ambas medidas, para ello, abrimos el Analizador de rendimiento en Ver à Analizador de Rendimiento:

 

 
 
 

En la nueva ventana que se nos ha abierto, pulsamos en Iniciar Grabación:

 
 

Y acto seguido se nos habilita la opción de Actualizar Objetos Visuales, y hacemos click:


 
 

Y nos devuelve unos valores tal que así:

 

 

Como podemos ver en las dos últimas filas, para la tarjeta TREATAS el tiempo de respuesta ha sido de 189 ms mientras que para la tarjeta que no usa la relación virtual el tiempo de respuesta ha sido de 149 ms. Si desplegamos el árbol en ambas tarjetas, vemos la repartición de tiempo por cada una de las tareas ejecutadas:

 

 
 

Como se puede ver, la diferencia de tiempo en la consulta DAX difiere en 5 ms sólo para este caso, que no es demasiado, pero esto lo extrapolamos a modelos de millones de registros pues el tiempo de ejecución del plan de consulta será mucho mayor. Todo esto, lo podemos llevar a la herramienta DAX Studio y analizarlo más a fondo (ya hablaremos más adelante de ella)

En vista de los resultados anteriores y ante la duda de qué relación crear, en primer lugar, la relación física activa, en segundo lugar, la relación física inactiva y en tercer lugar la relación virtual.

Dicho esto, la siguiente pregunta que os estaréis haciendo, si no es tan recomendable la relación virtual, ¿por qué, para qué y cuando la puedo utilizar? Pues como todo en esta vida depende, pues si por algún motivo no se puede crear la relación activa por ejemplo por alguna dependencia circular, puedo utilizar la relación virtual y usarla. 

En definitiva, las reglas generales o buenas prácticas de DAX son:

  • Utilizar siempre una relación física para propagar filtros siempre que sea posible.
  • Si no se puede usar una relación física, implementar una relación virtual usando TREATAS.

Si la granularidad del filtro propagado es relativamente pequeña, puede considerar una relación virtual como una posible alternativa a una física. El rendimiento más lento de una relación virtual no debería afectar el tiempo de ejecución general de manera visible, pero recuerde que su experiencia puede variar según la complejidad de la consulta.

 

¡Nos vemos en los datos!