Extracto del libro “Power BI Dataflows”
EL PLEGADO DE
CONSULTAS DESDE
FLUJOS DE DATOS
Francisco Mullor
Este capítulo es un extracto del libro “Power BI Dataflows” de Francisco Mullor Cabrera,
distribuido libre y gratuitamente por el propio autor con motivo de la Virtual Conf del canal de
telegram Power BI Español celebrada en Noviembre de 2021.
Para adquirir el ebook completo puede encontrar información en el siguiente link:
Power BI Dataflows - ([Link])
6. El plegado de consulta desde flujos de datos
Todos hemos oído hablar del plegado de consultas (query folding en inglés) y no muchos
conocemos exactamente de qué se trata.
Por definición, el plegado de consulta es la capacidad que tiene power query para traducir
la consulta al lenguaje del origen, de manera que sea éste quien resuelva íntegramente la petición.
El plegado de consultas es un tema muy importante en el modelado de datos por varios
motivos:
1
1º Las actualizaciones de datos en modelos de importación serán más eficaces en términos
de uso de recursos y de duración de la actualización cuanto más se respete el plegado de
consultas.
2º Cuando queremos trabajar con modelos de almacenamiento dual o DirectQuery sólo se
permitirán consultas de power query que se puedan plegar totalmente.
3º La actualización incremental de datos será eficaz sólo si se mantiene el plegado de
consulta, ya que, si la partición se realiza sobre un conjunto de datos que no admita el plegado,
el motor de mashup tendrá que recuperar todas las filas del origen y luego aplicar los filtros para
determinar los cambios incrementales.
En los flujos de datos de Power BI, desde enero de 2021, existe un elemento visual que nos
permite saber en cada paso si se ha roto o no el plegado, elemento que es tremendamente útil
para primero, poder aprender qué pasos de nuestras consultas suponen una ruptura del query
folding y segundo, cuando es imposible no romper el plegado de consulta, podemos mover los
pasos para hacerlos en un orden que permita que el plegado se rompa lo más tarde posible.
La mayoría de los orígenes de datos que tienen el concepto de lenguaje de consulta
admiten el plegado de consultas. Estos orígenes de datos pueden incluir bases de datos
relacionales, fuentes de OData (incluidas las listas de SharePoint), Exchange y Active Directory. Sin
embargo, los orígenes de datos como los archivos planos, blobs y web normalmente no lo hacen.
También admite el plegado de consultas, desde septiembre de 2021, los datos almacenados en
flujos de datos siempre y cuando se trabaje en una capacidad premium o premium per user y se
tenga activado el motor de consulta mejorado, como veremos en el tema VII de esta sección.
Siguiendo al pie de la letra el artículo sobre plegado de consultas de la documentación
oficial de Microsoft1, las transformaciones de orígenes de datos relacionales que se pueden plegar
son aquellas que se pueden escribir como una única instrucción SELECT. Una instrucción SELECT
se puede construir con las cláusulas WHERE, GROUP BY y JOIN apropiadas. También puede
contener expresiones de columna (cálculos) que usan funciones integradas comunes admitidas
por las bases de datos SQL.
Por lo general, en la lista siguiente se describen las transformaciones que se pueden doblar.
• Quitar columnas.
• Cambiar el nombre de las columnas (seleccione los alias de columna).
• Filtrar filas, con valores estáticos o parámetros de Power Query (predicados de la cláusula
WHERE).
• Agrupar y resumir (cláusula GROUP BY).
• Expandir las columnas de registro (columnas de clave externa de origen) para obtener
una combinación de dos tablas de origen (cláusula JOIN).
1
[Link]
MVP-5003973
2
• Combinación no aproximada de consultas que pueden doblarse en función del mismo
origen (cláusula JOIN).
• Anexar consultas que pueden doblarse en función del mismo origen (operador UNION
ALL).
• Agregar columnas personalizadas con lógica simple (expresiones de columna de la
instrucción SELECT). La lógica simple implica operaciones poco complicadas,
posiblemente incluyendo el uso de funciones M que tienen funciones equivalentes en el
origen de datos SQL, como matemáticos o funciones de manipulación de texto. Por
ejemplo, las expresiones siguientes devuelven el componente del año del valor de la
columna OrderDate (Fecha del pedido) (para devolver un valor numérico).
[Link]([OrderDate])
• Dinamizar y anular dinamización (operadores PIVOT y UnPivot).
3
El indicador visual del plegado de consulta muestra de manera visual en qué estado se
encuentra cada paso en cuanto a mantenimiento del plegado a través de los iconos visuales :
Indicador Icono Descripción
Pliega El indicador de plegado le indica que la
consulta hasta este paso será evaluada por la fuente
de datos.
No pliega El indicador de no plegado le indica que alguna
parte de la consulta hasta este paso se evaluará fuera
de la fuente de datos. Puedes compararlo con el
último indicador de plegado, si lo hay, para ver si
puedes reorganizar tu consulta para que tenga un
mayor rendimiento.
Podría plegarse Los indicadores de "podría" plegarse son poco
comunes. Significan que una consulta "podría"
plegarse. Indican que el plegado/no plegado se
determinará en tiempo de ejecución, al extraer los
resultados de la consulta, y que el plan de consulta es
dinámico. Es probable que sólo aparezcan con
conexiones ODBC u OData.
Opaco Los indicadores opacos le indican que el plan
de consulta resultante no es concluyente por alguna
razón. Por lo general, indica que hay una verdadera
tabla "constante", o que esa transformación o
conector no es compatible con los indicadores y la
herramienta de plan de consulta.
Desconocido Los indicadores desconocidos representan una
ausencia de plan de consulta, ya sea debido a un error
o al intento de ejecutar la evaluación del plan de
consulta en algo que no sea una tabla (como un
registro o una lista).
4
En Power BI Desktop una de las formas de saber si el plegado de consultas se mantiene o
no, es con botón derecho sobre el paso que queramos analizar ver si nos devuelve una consulta
nativa.
Si nos devuelve consulta nativa es señal inequívoca de que el plegado de mantiene y esa
es la consulta que elevará al origen en el plan de ejecución.
En los flujos de datos de Power BI también existe esa posibilidad de ver la consulta nativa:
Pero, además, el indicador visual nos va a mostrar de una manera más efectiva en qué estado
está y cuando se ha roto el plegado.
5
Veamos qué transformaciones mantienen el plegado. Para ello voy a utilizar como siempre
una conexión SQL local a la base de datos de Contoso, en este caso sobre la DimProducto.
1) Seleccionar columnas o quitar otras columnas mantiene el plegado:
Hay que tener en cuenta en este caso que simplemente aplicamos una instrucción Select
al origen SQL.
2) Filtrar filas también mantiene el plegado:
6
En este caso simplemente aplica además de al select, una clausula where
3) Cambiar el nombre de las columnas también mantiene el plegado:
7
Está simplemente añadiendo un as [Campo] a la sentencia SQL que se lanza contra el
origen.
Agrupar y resumir mantiene el plegado:
Si en la tabla de productos se agrupa por ejemplo por Subcategoría para saber el nº de
productos que tenemos por cada una de ellas con un recuento, esta transformación equivale a
un GROUP BY de SQL y mantiene sin ningún problema el plegado.
8
No obstante, agrupaciones complejas que no se hagan con la interfaz pueden no plegarse
aunque tengan una traducción a SQL. Por ejemplo, algo muy habitual es necesitar agrupar y
quedarse sólo con la línea más reciente, voy a aprovechar para explicar cómo lo hago yo, se verá
que no admite plegado y que además existe traducción a SQL.
Si sobre la factVentas de contoso lanzamos la siguiente instrucción SQL:
Select * from
(
select row_number() over (partition by channelKey order by saleskey
desc) as row#
,SalesAmount,channelKey, DateKey
from FactSales ) h
where [Link]#=1
Nos devuelve la última venta para cada canal de venta.
Esto en power query no se puede hacer con la interfaz, pero yo lo hago de una manera
muy sencilla “tocando” el código M en el editor de consulta. Sobre la factSales, ordeno
descendentemente en función de la saleskey como he hecho en SQL y agrupo trayéndome en el
nivel agregado “Todas las filas”.
9
Y, aquí está la magia…
#"Filas agrupadas" = [Link](#"Filas ordenadas", {"channelKey"}, {
{"Todas", each _, type nullable table[SalesKey = [Link], DateKey = date
time, channelKey = [Link], StoreKey = [Link], ProductKey = [Link]
pe, PromotionKey = [Link], CurrencyKey = [Link], UnitCost = Currenc
[Link], UnitPrice = [Link], SalesQuantity = [Link], ReturnQuanti
ty = [Link], ReturnAmount = nullable [Link], DiscountQuantity =
nullable [Link], DiscountAmount = nullable [Link], TotalCost = C
[Link], SalesAmount = [Link], ETLLoadID = nullable [Link],
LoadDate = nullable datetime, UpdateDate = nullable datetime, DimChannel =
nullable record, DimCurrency = nullable record, DimDate = nullable record,
DimProduct = nullable record, DimPromotion = nullable record, DimStore = n
ullable record]}})
Sobre el “_” tras el each que es el identificador de la tabla anidada que se genera, realizo
un [Link](_,1) quedando el código así:
#"Filas agrupadas" = [Link](#"Filas ordenadas", {"channelKey"}, {
{"Todas", each [Link](_,1), type nullable table[SalesKey = [Link]
, DateKey = datetime, channelKey = [Link], StoreKey = [Link], Produ
ctKey = [Link], PromotionKey = [Link], CurrencyKey = [Link], Un
itCost = [Link], UnitPrice = [Link], SalesQuantity = [Link]
pe, ReturnQuantity = [Link], ReturnAmount = nullable [Link], Dis
countQuantity = nullable [Link], DiscountAmount = nullable [Link]
e, TotalCost = [Link], SalesAmount = [Link], ETLLoadID = null
able [Link], LoadDate = nullable datetime, UpdateDate = nullable dateti
me, DimChannel = nullable record, DimCurrency = nullable record, DimDate =
nullable record, DimProduct = nullable record, DimPromotion = nullable reco
rd, DimStore = nullable record]}})
Lo que consigo con este código es el mismo efecto que en sql se consigue con el where
[Link]#=1, es decir traer sólo la primera línea de la tabla que se anida. Se expande SalesAmount y
DateKey y se obtiene la misma tabla que en SQL:
10
El resultado como vemos es el mismo, sin embargo, esta agrupación compleja, pese a
tener traducción a SQL como hemos visto, no admite plegado.
Además, este tipo de funciones cuando la tabla anidada que se genera es muy grande
como es el caso de la agrupación que hemos hecho en la tabla de hechos de contoso, tardan
bastante en procesarse en el Mashup de Power Query mientras la consulta SQL devolvía los datos
en apenas 3 segundos.
Por ello, la recomendación será siempre hacer todo este tipo de transformaciones
directamente en el origen siempre que sea posible, bien mediante una vista, o bien, como
veremos más adelante en este capítulo, mediante una consulta nativa que podrá mantener
posteriormente el plegado de la forma que se referenciará en su momento.
4) Expandir las columnas de registro mantiene el plegado
Cuando las tablas de origen están relacionadas, se pueden traer anidadas como columnas
dentro de la tabla con la que se relacionan. Es lo que se define en el origen de datos con el check
de “Incluir columnas de relación”
11
Pues bien, estas columnas de relación pueden expandirse para traer campos de las tablas
relacionadas, por ejemplo, la subcategoría y la categoría dentro de la dimensión producto. Y este
“mecanismo de join” mantiene el plegado de consulta.
Sobre estas columnas de relación indicar que provocan un
warning cuando estás creando el flujo de datos porque este tipo de
columnas que define como tipos complejos no pueden cargarse en
el continente de los flujos de datos que es un csv.
Pero esa advertencia no es ningún problema ya que aun en el caso de que se cierre y se
guarde el flujo con el warning activo, el flujo se actualizará correctamente y si volvemos a su
edición se puede observar que automáticamente cuando la tabla tiene ese warning el flujo crea
un paso de eliminación de los tipos complejos no soportados:
#"Quitar columnas" = [Link](Navegación, [Link]
Type(Navegación, {type table, type record, type list, type nullable binary,
type binary, type function}))
in
#"Quitar columnas"
12
Volviendo al tema tras ese breve paréntesis, podemos traernos cualquier campo de la tabla
relacionada manteniendo el plegado como he dicho y como se puede ver en el ejemplo
Siempre que tengamos las relaciones en el origen bien definidas, con esta técnica además
nos evitamos el problema de las entidades calculadas (aunque ya se vio que no es tal problema)
5) Combinar consultas del mismo origen mantiene el plegado
Pero no siempre se tendrá las tablas bien relacionadas en el origen por lo que en muchas
ocasiones se deben hacer combinaciones entre tablas. Las combinaciones entre tablas, si son del
mismo origen y ambas tablas mantienen el plegado, también pliegan. Así se puede combinar
nuestra dimensión producto con nuestra dimensión subcategoría
13
Lo que daría lugar a una tabla calculada que como se vio en el capítulo anterior puede
evitarse deshabilitando la carga de la tabla subcategoría.
Pero ojo a lo que matizábamos…” cuando se trata de combinaciones de dos tablas que
mantienen el plegado”. Si no mantengo el plegado en la tabla Subcategoría… (he hecho un
[Link]() que es infalible para romperlo)
14
Automáticamente mi tabla de Productos no mantiene el plegado tras expandir la tabla de
subcategoría:
6) Anexar consultas del mismo origen mantiene el plegado
Al igual que la combinación, la anexión mantiene el plegado cuando se trata de tablas del
mismo origen y que a su vez ambas mantienen el plegado. Voy a modo de ejemplo simplemente
a duplicar mi tabla DimChannel y anexar la duplicada a la que ya existía:
15
Hay que tener en cuenta lo explicado sobre tablas calculadas que se evita deshabilitando
la carga de DimChannel(2)
Y el plegado se mantiene
Pero igual que decíamos en el anterior ejemplo si se rompe el plegado en la tabla anexada,
se rompe en la principal:
7) Agregar consultas personalizadas con lógica simple mantiene el plegado
La creación de columnas personalizadas, siempre que contengan una lógica simple que
sea traducible al lenguaje del origen mantendrá el plegado. Así, se pueden ver los siguientes
ejemplos:
• Extraer el año de una fecha:
16
Esto se traduce en el origen sql como
datepart("yyyy", [_].[LoadDate]) as
[Personalizado] y mantiene el plegado.
Nótese la nueva opción sólo disponible en
los flujos de datos de introducir el tipo de
datos en la columna personalizada
ahorrándose un paso o editar el código.
Igualmente hay que señalar que la
conversión de tipos rompe el plegado ilógicamente, ya que existe forma en el lenguaje
de origen de convertir los tipos y en el caso del datepart no admite su transformación
en entero sin romper el plegado cuando parecería lo lógico.
• Crear una columna condicional:
Este tipo de columnas condicionales mantiene el plegado ya que tiene su traducción en el
lenguaje de origen con CASE WHEN…
case
when [_].[ChannelLabel] = '01'
then 'Local'
else ' Online'
end as [Condicion]
• Concatenación de textos:
La concatenación de textos también mantiene el plegado al traducirse fácilmente
al lenguaje del origen
17
([_].[ChannelName] + ' - ') + [_].[t0_02] as [Concatenacion de textos]
En todo caso advertir que la sintaxis de la consulta nativa que crea el sistema, para
cualquier experto en sql se antoja bastante rara, ya que a medida que se van realizando pasos va
creando subqueries anidadas sin simplificar el lenguaje.
De este modo, esta sencilla Query de M con tres columnas personalizadas:
let
Origen = [Link]("DESKTOP-4B9T98R\FRANSQL", "Contoso"),
Navigation = Origen{[Schema = "dbo", Item = "DimChannel"]}[Data],
#"Columnas quitadas" = [Link](Navigation, {"FactSales", "FactSa
lesQuota"}),
#"Personalizado agregado" = [Link]([Link](#"Col
umnas quitadas", "Personalizado", each [Link]([LoadDate])), {{"Personalizado", t
ype number}}),
#"Personalizado agregado 1" = [Link]([Link](#"P
ersonalizado agregado", "Condicion", each if [ChannelLabel]="01" then "Local" else
" Online"), {{"Condicion", type text}}),
#"Personalizado agregado 2" = [Link]([Link](#"P
ersonalizado agregado 1", "Concatenacion de textos", each [ChannelName] & " - " & [
Condicion]), {{"Concatenacion de textos", type text}})
in
#"Personalizado agregado 2"
Da lugar a esta enrevesada consulta de SQL:
select [_].[ChannelKey] as [ChannelKey],
[_].[ChannelLabel] as [ChannelLabel],
[_].[ChannelName] as [ChannelName],
[_].[ChannelDescription] as [ChannelDescription],
[_].[ETLLoadID] as [ETLLoadID],
[_].[LoadDate] as [LoadDate],
[_].[UpdateDate] as [UpdateDate],
[_].[t0_0] as [Personalizado],
[_].[t0_02] as [Condicion],
18
convert(nvarchar(max), [_].[Concatenacion de textos]) as
[Concatenacion de textos]
from
(
select [_].[ChannelKey] as [ChannelKey],
[_].[ChannelLabel] as [ChannelLabel],
[_].[ChannelName] as [ChannelName],
[_].[ChannelDescription] as [ChannelDescription],
[_].[ETLLoadID] as [ETLLoadID],
[_].[LoadDate] as [LoadDate],
[_].[UpdateDate] as [UpdateDate],
[_].[Personalizado] as [Personalizado],
[_].[Condicion] as [Condicion],
[_].[t0_0] as [t0_0],
[_].[t0_02] as [t0_02],
([_].[ChannelName] + ' - ') + [_].[t0_02] as [Concatenacion de
textos]
from
(
select [_].[ChannelKey] as [ChannelKey],
[_].[ChannelLabel] as [ChannelLabel],
[_].[ChannelName] as [ChannelName],
[_].[ChannelDescription] as [ChannelDescription],
[_].[ETLLoadID] as [ETLLoadID],
[_].[LoadDate] as [LoadDate],
[_].[UpdateDate] as [UpdateDate],
[_].[Personalizado] as [Personalizado],
[_].[Condicion] as [Condicion],
[_].[Personalizado] as [t0_0],
convert(nvarchar(max), [_].[Condicion]) as [t0_02]
from
(
select [_].[ChannelKey] as [ChannelKey],
[_].[ChannelLabel] as [ChannelLabel],
[_].[ChannelName] as [ChannelName],
[_].[ChannelDescription] as [ChannelDescription],
[_].[ETLLoadID] as [ETLLoadID],
[_].[LoadDate] as [LoadDate],
[_].[UpdateDate] as [UpdateDate],
datepart("yyyy", [_].[LoadDate]) as [Personalizado],
case
when [_].[ChannelLabel] = '01'
then 'Local'
else ' Online'
end as [Condicion]
from [dbo].[DimChannel] as [_]
) as [_]
) as [_]
) as [_]
Estos son algunos ejemplos de columnas personalizadas que mantienen el plegado, seguro
que hay muchas más, lo importante es que con el control visual del plegado en todo momento
se puede revisar si el plegado se mantiene o no.
19
8) Dinamizar y anular dinamización mantiene el plegado.
Dinamizar o anular la dinamización de columnas (pivot y unpivot en inglés) también
mantiene sin problemas el plegado ya que traduce a la función UNPIVOT de SQL
[$Pivot] unpivot ([Valor] for [Atributo] in ([ChannelKey])) as [$Table]
Por otro lado, existen una serie de funciones que a priori parecería que mantuvieran el
plegado y sin embargo no lo hacen. Por ejemplo, cambiar el tipo de datos. Cambiar una columna
de número decimal a entero incomprensiblemente rompe el plegado
En este caso he cambiado la columna “Personalizado” que se había creado con [Link]
y que para no romper el plegado hay que mantenerla como tipo number.
Agregar un índice a la tabla también rompe el plegado.
Como vimos anteriormente la instrucción [Link]() como es obvio rompe el
plegado
Transponer una tabla también lo rompe.
Promover o disminuir la fila del encabezado también rompe el plegado.
Dividir columna por delimitador también lo rompe
20
Y así un buen número de funciones no son traducibles al lenguaje de origen y rompen el
plegado.
6.1 Uso del plan de consultas
Junto al objeto visual que permite controlar el mantenimiento del plegado de consultas, el
equipo de producto de flujos de datos en la misma actualización desarrolló el visor del plan de
consultas para ayudar en la tarea de identificar la ruptura del plegado y poder determinar acciones
a realizar para su mantenimiento o su ruptura lo más tarde posible.
Cuando se visualiza el plan de consulta de una consulta que mantiene el plegado, el plan
de consulta siempre va a ser como el de la imagen:
Un origen de datos que admite plegado, en este caso [Link] y una consulta nativa
que es la petición de datos que el Mashup de Power Query realiza al origen.
Conocer y experimentar con el plan de consulta de los flujos de datos nos va a permitir
poder realizar cambios en nuestras consultas para optimizarlas. Véase algún ejemplo:
Sobre mi tabla de productos, voy a saltarme todas las buenas prácticas y romper el plegado
en el primer paso, convirtiendo el tipo del “ProductNameLabel” que es un texto a decimal.
21
El plegado se ha roto ya que como se dijo cambiar los tipos es una de las causas de ruptura
del plegado.
Observe el lector las consecuencias que a nivel de plan de ejecución de la consulta tiene la
ruptura del plegado. Tras realizar la consulta y traerse todos los datos del origen, se crea una
nueva columna con el cambio, se seleccionan todas las columnas del origen menos la cambiada
y la nueva columna creada, se renombra la nueva columna y se reordenan las columnas para que
se queden como estaban. Un simple cambio de tipo de datos que no pliega.
Hay una serie de buenas prácticas que debemos seguir en la realización de nuestros
procesos de ETL
Si posteriormente a este paso creamos un paso que hubiera mantenido el plegado pueden
pasar varias cosas y el plan de consultas nos va a ayudar a decidir qué decisión tomar.
Si, por ejemplo, tras cambiar el tipo y romper el plegado se eligen las columnas que se van
a necesitar en el modelo el motor va a ser capaz de entender que esa transformación puede
realizarse previamente al cambio de tipos y mandar la instrucción de elección de columnas
directamente en la consulta nativa.
22
Se eligen columnas y se observa que el plegado está roto.
Sin embargo, vean el plan de consultas…
El flujo de datos es capaz de determinar que la selección de columnas puede plegarse y
hace el select como si fuera un paso previo a la ruptura del plegado.
Si en el siguiente paso filtramos una columna, igualmente es capaz de introducir el where
en la consulta nativa pese a la ruptura del plegado.
23
Sin embargo, no pasa con todas las transformaciones que admiten plegado, porque si, por
ejemplo, combinásemos en este momento nuestra tabla de productos con la de subcategorías, el
flujo no sería capaz de crear el join en la consulta nativa como se puede ver en la imagen del
plan de consultas:
El análisis de este plan de consultas nos ayudaría a decidir que el paso del cambio de tipos
debe llevarse el último lugar con la idea de mantener el plegado hasta el final
24
Pero si no se hubiera necesitado el join y se analiza el plan de consultas en el paso de
filtrado, nos ayudaría a decidir que no era necesario cambiar el paso del tipo hacia abajo ya que
mantendría el plegado en los dos pasos posteriores.
En definitiva y como resumen.
1º Hay que intentar mantener el plegado lo máximo posible
2º El plan de consultas nos puede ayudar a decidir acciones para mejorar el rendimiento
de nuestras consultas
3º Los flujos de datos están optimizados para la agrupación de los pasos del mismo tipo y
el envío de pasos que mantienen el plegado dentro de la consulta nativa, aunque se haya roto el
plegado en un paso anterior.
6.2 Mantenimiento del plegado con consultas nativas
Hasta finales de febrero de 2021, utilizar una consulta nativa en aquellos orígenes que la
soportan como SQL para traer la información rompía el plegado de consultas. Cualquier
transformación posterior se evaluaba en el mashup. De hecho, si utilizamos actualmente el cuadro
de diálogo de la interfaz para crear una consulta nativa, inmediatamente rompemos el plegado.
25
Creamos una consulta nativa para traernos la tabla de productos completa.
La primera vez que conectamos una consulta nativa en un flujo de datos se tiene que validar
que queremos utilizar este tipo de conexión.
Si creamos posteriormente un paso de selección de columnas o un paso de filtrado de
columnas que se vio que son pasos que mantienen el plegado, sin embargo, si se hacen sobre
una conexión al origen con consulta nativa, el plegado no se mantiene y podemos observar el
plan de consultas que establece internamente.
26
Pero como comentaba esto cambió a finales de febrero de 2021 cuando Chris Webb 2
anunció en su blog que se había habilitado la forma de poder enviar una consulta nativa al origen
manteniendo el plegado de consultas en los pasos posteriores que lo posibiliten. Para ello la
instrucción debe realizarse en el editor de consulta ya que no se admite el comando
“EnableFolding=true” directamente en el cuadro de dialogo de la consulta nativa en la
interfaz, este comando es una opción para la función que se va a estudiar a continuación.
[EnableFolding=true], este es el comando clave.
Para crear una consulta nativa sin la utilización de la interfaz se utiliza la función
[Link].
Si vemos la documentación de la función a través del propio flujo de datos nos
encontramos los siguientes parámetros:
2
[Link]
using-value-nativequery-and-enablefoldingtrue/
27
target: proporciona el contexto para la operación descrita en la Query, es por tanto
donde se llama al origen de los datos a los que nos vamos a conectar, por ejemplo a través de la
función [Link](Servidor,BaseDeDatos)
query: es la instrucción que se va a ejecutar en el target, por ejemplo, en el caso de utilizar
la conexión a SQL, pues la consulta en T-SQL
parameters: puede contener parámetros que se podrían definir con posterioridad, pero
debemos tener en cuenta que para que se mantenga el plegado es absolutamente indispensable
que no se utilicen parámetros en la query, por lo que este parámetro debe ponerse siempre “null”.
options: puede incluirse un registro opcionalmente que contenga opciones (valga la
redundancia) que afecten al comportamiento de la Query en el target. En este registro es donde
podemos utilizar nuestro comando [EnableFolding = true] para el mantenimiento posterior
del plegado de consultas.
Cuando utilizamos el conector [Link] y con el cuadro de diálogo introducimos
una consulta nativa, esta consulta es una de las opciones admitidas por el conector creando en el
código un sentencia [Query=”…“], pero este conector, ni ningún otro admiten el
EnableFolding=true como opción, excepto el [Link].
Véase como construirla:
Podemos hacerlo en un paso o en dos:
En dos pasos:
1º Conectarse a nuestro origen SQL con la función [Link]:
let
Origen = [Link]("DESKTOP-4B9T98R\FRANSQL", "Contoso)
in
Origen
2º Utilizar nuestra función [Link], llamando en primer lugar al origen,
definiendo en segundo lugar la Query, utilizando null en el tercer argumento de los parámetros y
por último en el 4º argumento utilizando nuestro registro [EnableFolding=true], quedando
así:
let
Origen = [Link]("DESKTOP-4B9T98R\FRANSQL", "Contoso"),
ConsultaNativa = [Link](Origen, "select * from DimProduct
", null, [EnableFolding = true])
in
ConsultaNativa
28
En un solo paso:
Integrando nuestra llamada al origen en la propia [Link] así:
let
Origen = [Link] ([Link]("DESKTOP-
4B9T98R\FRANSQL", "Contoso"),
"select * from DimProduct", null, [EnableFolding = true])
in
Origen
En ambos casos obtenemos el mismo resultado: una consulta nativa al origen que continúa
plegando como vemos en la imagen.
29
6.3 Desmitificando el plegado de consulta. Conclusiones.
Para concluir este tema tan apasionante como es el plegado de consulta propondría esta
serie de conclusiones, muy personales y que seguramente no estén alineadas con muchos autores,
pero son mis reflexiones en voz alta:
1º Siempre que se pueda, hay que mantener el plegado de consulta lo máximo posible y el
control visual del plegado es una herramienta fantástica que nos ayudará en todo momento a
saber si lo estamos manteniendo.
2º Si advertimos que un paso rompe el plegado, utilizar el plan de consultas para verificar
como está evaluando el mashup nuestro código intentando en todo caso optimizarlo. El mashup
de todas formas va a optimizar al máximo la consulta como se vio mediante ejemplos, pero hay
pasos que admitiendo plegado antes de romperlo no pliegan con posterioridad y son los que hay
que analizar y evitar hacerlos con posterioridad a la ruptura.
3º Las buenas prácticas tradicionales que se apuntaban sobre economizar los pasos, hacer
todos los pasos del mismo tipo juntos, etc. es bueno observarlas por economía de la consulta,
ésta será mucho más fácil de leer, pero a nivel de rendimiento (siempre se analizará con el plan
de consulta) ya se ha visto que el motor del mashup en Power Query online va a tener la capacidad
de agrupar las transformaciones del mismo tipo.
4º Romper el plegado no implica en la mayoría de los casos que nuestra consulta no se
vaya a ejecutar, simplemente será menos eficiente en su ejecución. Por tanto, hay que darle
importancia, pero no volverse loco.
5º En el momento en que realizas transformaciones muy complejas, el plegado se romperá,
tened en cuenta que si fueran sencillas estarían incluidas en la interfaz y seguramente plegarían,
por ello trabajar con funciones de lista o trabajar con funciones personalizadas, romperá casi
siempre el plegado y no por ello debemos dejar de utilizarlas. Por lo general cualquier cosa que
hagamos a “espaldas” de la interfaz romperá el plegado.
6º Si sabes T-SQL (o el lenguaje del origen), siempre se dice que las transformaciones
cuanto más cerca del origen mejor por lo que si puedes, haz una vista en la base de datos y si no
puedes crear vistas, utiliza las consultas nativas, teniendo en cuenta como se ha visto que pueden
seguir plegando si se hacen de la forma adecuada.
30