¡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!