SUMMARIZE vs SUMMARIZECOLUMNS vs GROUPBY: cuándo y por qué usar cada uno
Representar datos de forma agregada es la base del Business Intelligence. En DAX, tenemos tres funciones principales para agrupar tablas: SUMMARIZE, SUMMARIZECOLUMNS y GROUPBY. Aunque a simple vista parecen intercambiables, sus motores internos, su comportamiento con el contexto de filtro y su impacto en el rendimiento son radicalmente distintos. En proyectos reales de retail o industria, elegir la función incorrecta no solo ralentiza el informe, sino que puede devolver resultados erróneos en los totales de las tablas.
Como consultores, a menudo heredamos modelos donde se abusa de SUMMARIZE para añadir columnas de cálculo. Esta es una de las principales fuentes de ineficiencia. Antes de optimizar, debemos entender que cada función fue diseñada para un escenario concreto. Mientras una está optimizada para consultas externas (Reporting Services o el propio motor de visualización de Power BI), otra es una herramienta de legado que requiere precaución, y la tercera es una utilidad de nicho para iteraciones complejas en memoria.
En este artículo desglosamos por qué SUMMARIZECOLUMNS debe ser tu opción por defecto, por qué nunca deberías usar SUMMARIZE para calcular métricas y en qué escenarios específicos GROUPBY es la única solución técnica viable para evitar el escaneado masivo de tablas en el Storage Engine.
SUMMARIZE: La función de legado y el peligro de los totales
La función SUMMARIZE es la más antigua de las tres. Su sintaxis permite agrupar por columnas de una tabla y, opcionalmente, añadir nuevas columnas con cálculos agregados. Sin embargo, su uso para crear columnas calculadas dentro de la propia función se considera hoy una mala práctica en casi todos los escenarios profesionales.
El problema fundamental de SUMMARIZE cuando añade columnas es que realiza una transición de contexto implícita que puede generar resultados inesperados. Esto ocurre porque el motor de DAX intenta realizar un agrupamiento que no siempre respeta la granularidad deseada en el cálculo de las medidas, especialmente cuando entran en juego filtros complejos. Además, el rendimiento es notablemente inferior al de sus alternativas modernas.
El patrón SUMMARIZE + ADDCOLUMNS
Si necesitas usar SUMMARIZE para crear una tabla física o una tabla intermedia en una medida, la recomendación técnica es usarla exclusivamente para agrupar columnas y envolverla en un ADDCOLUMNS para los cálculos. Este patrón asegura que los cálculos se realicen sobre la tabla ya agrupada, manteniendo la claridad del contexto de filtro y permitiendo que el optimizador de consultas trabaje de forma más eficiente.
-- PATRÓN RECOMENDADO: SUMMARIZE para agrupar, ADDCOLUMNS para calcular
VAR TablaVentasAgrupada =
ADDCOLUMNS(
SUMMARIZE(
Ventas,
Ventas[ProductoID],
Ventas[TiendaID]
),
"Total Ventas", [Importe Total],
"Unidades", SUM(Ventas[Unidades])
)
RETURN
TablaVentasAgrupadaEste enfoque evita el error común de los totales incorrectos y es más fácil de depurar con herramientas como DAX Studio. Si vienes de otros lenguajes como SQL, SUMMARIZE es lo más parecido a un GROUP BY básico, pero en DAX su semántica es más traicionera de lo que parece.
SUMMARIZECOLUMNS: El estándar de oro en rendimiento
Introducida para optimizar las consultas de Power BI, SUMMARIZECOLUMNS es la función más potente y rápida para agrupar datos. A diferencia de SUMMARIZE, no requiere una tabla base como primer argumento; simplemente enumeras las columnas por las que quieres agrupar y las columnas que quieres calcular.
Es importante destacar que SUMMARIZECOLUMNS está altamente optimizada para el Storage Engine (VertiPaq). Es capaz de aplicar filtros directamente dentro de la función (argumentos de filtro opcionales), lo que reduce drásticamente la cantidad de datos que el Formula Engine debe procesar después. Es la función que Power BI utiliza internamente cuando arrastras campos a un objeto visual de tabla o matriz.
La limitación crítica de SUMMARIZECOLUMNS
A pesar de su superioridad técnica, SUMMARIZECOLUMNS tiene una restricción que frustra a muchos desarrolladores: no se puede ejecutar en un contexto donde exista una transición de contexto activa. Esto significa que no puedes usarla dentro de un CALCULATE que esté siendo iterado por un SUMX, ni en una columna calculada de una tabla que tenga relaciones activas, a menos que uses funciones específicas de manipulación de filtros.
Si intentas usarla en una medida que se llama dentro de un objeto visual con filas, es probable que obtengas un error de ejecución. En esos casos, es necesario volver al patrón ADDCOLUMNS(SUMMARIZE(...)) o entender bien el uso de KEEPFILTERS en CALCULATE para gestionar cómo se propagan los filtros.
-- Uso óptimo de SUMMARIZECOLUMNS con filtros integrados
EVALUATE
SUMMARIZECOLUMNS(
'Producto'[Categoría],
'Calendario'[Año],
TREATAS({2023, 2024}, 'Calendario'[Año]), -- Filtro eficiente
"Ventas Netas", [Importe Total],
"Ranking", [RANKING_VENTAS] -- Reutiliza medidas existentes
)GROUPBY: Agrupación sobre tablas en memoria
La función GROUPBY es distinta. No realiza transiciones de contexto y no accede directamente al Storage Engine de la misma forma que las anteriores. Su propósito principal es agrupar tablas que ya han sido creadas en memoria mediante otras funciones DAX (como el resultado de un FILTER o un UNION).
En GROUPBY, para realizar cálculos sobre los grupos creados, debes usar la función CURRENTGROUP(). Esto permite realizar agregaciones anidadas (double aggregation) sin salir del contexto de la tabla virtual. Es una técnica avanzada que solemos emplear cuando necesitamos agrupar sobre una granularidad que no existe físicamente en el modelo, sino que es fruto de un cálculo previo.
En términos de rendimiento, GROUPBY suele ser más lenta que SUMMARIZECOLUMNS porque depende más del Formula Engine. Sin embargo, en escenarios de modelos en DirectQuery o cuando trabajamos con lógicas que requieren evitar la transición de contexto a toda costa, es una herramienta indispensable.
Comparativa técnica y decisiones de arquitectura
Para elegir correctamente, debemos evaluar tres factores: dónde se ejecuta el código, qué tipo de filtros se aplican y si necesitamos que la función sea «consciente» del contexto de fila existente.
| Característica | SUMMARIZE | SUMMARIZECOLUMNS | GROUPBY |
|---|---|---|---|
| Uso recomendado | Agrupar columnas físicas | Consultas de alto rendimiento y tablas calculadas | Agrupación de tablas virtuales (en memoria) |
| Transición de contexto | Sí (peligroso en cálculos) | No (falla si hay contexto de fila) | No |
| Cálculos integrados | Evitar (usar ADDCOLUMNS) | Nativo y optimizado | Nativo mediante CURRENTGROUP() |
| Rendimiento SE | Medio | Muy Alto | Bajo/Medio |
| Filtros internos | No | Sí (argumentos dedicados) | No |
En el día a día de un consultor, la decisión suele ser binaria: si es una tabla calculada o una consulta externa, usamos SUMMARIZECOLUMNS. Si es una lógica interna de una medida compleja donde necesitamos agrupar algo que ya hemos filtrado previamente en una variable, optamos por ADDCOLUMNS(SUMMARIZE(...)) por compatibilidad, o GROUPBY si la lógica de agregación es muy específica.
Errores frecuentes detectados en auditorías de rendimiento
- Usar SUMMARIZE para añadir medidas: Como ya hemos mencionado, esto genera un plan de consulta ineficiente. El motor debe realizar un trabajo extra para asegurar que la medida se calcula correctamente para cada combinación de filas. Siempre es mejor separar la agrupación del cálculo.
- Ignorar el efecto de las filas vacías:
SUMMARIZECOLUMNSelimina por defecto las filas donde todas las métricas son BLANK. Si necesitas ver todas las combinaciones (cross join), debes usar la funciónIGNORE()dentro de los argumentos. - Confundir granularidades: Un error común es agrupar por una columna de la tabla de hechos en lugar de la tabla de dimensiones. Esto invalida el uso eficiente de los índices del modelo en estrella.
- No medir el impacto: Antes de cambiar un
SUMMARIZEpor unSUMMARIZECOLUMNS, usa el Performance Analyzer. A veces, la diferencia en milisegundos no justifica la complejidad de reescribir una medida que ya funciona, pero en modelos de gran volumen (sectores como energía o retail con millones de tickets), el ahorro puede ser de segundos.
Es vital recordar que la optimización DAX no se trata solo de la función, sino de cómo esta interactúa con el modelo. Un mal diseño de relaciones hará que incluso un SUMMARIZECOLUMNS bien escrito sea lento. Si tienes dudas sobre cómo se comportan las agregaciones básicas, te recomiendo revisar nuestra comparativa técnica entre SUM y SUMX.
Cuándo calcular tablas intermedias en memoria
A menudo me preguntan si merece la pena crear tablas virtuales pesadas dentro de una medida. La respuesta depende del volumen. En modelos que gestionan millones de filas, crear una tabla virtual con SUMMARIZECOLUMNS para luego iterar sobre ella con un SUMX o un RANKX para controlar empates es mucho más eficiente que intentar realizar el cálculo directamente sobre la tabla de hechos.
Al reducir la granularidad en una variable intermedia, el motor trabaja con miles de filas en lugar de millones en los pasos finales del cálculo. Este es el secreto de las medidas rápidas en dashboards ejecutivos de alta densidad de datos.
Checklist para elegir la función de agrupación
- ¿Es para una tabla calculada o una consulta externa? Usa
SUMMARIZECOLUMNS. - ¿Necesitas agrupar dentro de una medida que ya tiene un contexto de fila activo? Usa
ADDCOLUMNS(SUMMARIZE(...)). - ¿Estás agrupando una tabla que ya es una variable (tabla virtual)? Usa
GROUPBY. - ¿Quieres filtrar datos dentro de la propia función de agrupación? Usa
SUMMARIZECOLUMNS. - ¿Te preocupan los totales incorrectos en tablas complejas? Evita las columnas calculadas dentro de
SUMMARIZE.
Preguntas frecuentes
¿Por qué SUMMARIZECOLUMNS da error en mis medidas?
Porque no soporta contextos de fila activos. Si la medida se usa en un objeto visual que itera filas o dentro de un iterador como SUMX, SUMMARIZECOLUMNS detecta esa ambigüedad y detiene la ejecución para evitar resultados impredecibles.
¿Es GROUPBY siempre más lento que SUMMARIZE?
Generalmente sí, porque GROUPBY no utiliza las optimizaciones de agregación del Storage Engine de la misma manera. Sin embargo, es más seguro cuando necesitas realizar múltiples agregaciones sobre una misma tabla virtual sin activar transiciones de contexto accidentales.
¿Cuándo debería preocuparme por el rendimiento de estas funciones?
Cuando el tiempo de respuesta de tus visuales supere los 200-300ms en el Performance Analyzer. En modelos pequeños (menos de 1 millón de filas), las diferencias son imperceptibles, pero en entornos de producción con grandes volúmenes, la elección de la función de agrupación define la usabilidad del informe.
»


