Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Reply
Syndicate_Admin
Administrator
Administrator

Complexity RLS - ¡Ayuda, por favor!

¡Hola a todos, buenas noches! Necesito ayuda.

Recientemente, un usuario se puso en contacto diciendo que no podía usar uno de nuestros informes de Power BI. Al principio, me pareció extraño porque él era el único que reportaba problemas — todos los demás siempre han usado el informe normalmente. Es un informe limpio y bien optimizado siguiendo las mejores prácticas, así que no tenía sentido que solo él estuviera experimentando una lentitud tan extrema.

Hice una videollamada con él y confirmé el problema: el informe era prácticamente inutilizable, nada cargaba — y de nuevo, esto solo le pasaba a él. Aún peor, su lentitud consumía una enorme parte de mi capacidad de Fabric (estoy usando Embedded).

Empecé a investigar y descubrí que el problema estaba relacionado con los roles de RLS a los que se le asigna. Es gerente, así que pertenece a 25 roles diferentes en RLS, cada uno relacionado con un centro de costes. Actualmente, todos estos roles comparten la misma particularidad: cada norma RLS contiene dos códigos de centro de costes (uno antiguo y otro nuevo debido a una incorporación reciente). Por ejemplo:

  • Regla 1: Código 1 Antiguo O Código 1 Nuevo
  • … y así sucesivamente, hasta la regla 25.

Tras profundizar, noté que usar la sala de operaciones dentro de RLS perjudica significativamente el rendimiento — y parece que esto es exactamente lo que está rompiendo el informe para este usuario en concreto.

Probé a reemplazar OR por IN, pero el rendimiento era exactamente el mismo, sin ninguna mejora.

Mi pregunta es: ¿cómo puedo solucionar esto?

Pensé en cambiar a RLS dinámico usando USERNAME(). Sin embargo, surgieron dos problemas:

  1. Mantenimiento manual: Tendría que añadir y quitar constantemente a personas de esta mesa. Y se convertiría en una mesa enorme, ya que tenemos casi 1.000 empleados.
  2. Flexibilidad limitada: este enfoque funciona bien si solo necesito filtrar por centro de costes. Pero si necesito ocultar información de otra tabla (como "sección"), no creo que eso lo solucione (al menos hasta donde tengo entendido).

Preguntas:

  • ¿Alguien se ha enfrentado a algo similar?
  • ¿Existe una forma más eficiente de manejar varios roles complejos de RLS?
  • ¿Existe algún enfoque de modelado que evite esta caída de rendimiento, especialmente cuando un usuario pertenece a muchos roles RLS?

Cualquier ayuda será muy apreciada. ¡Gracias!

7 REPLIES 7
Syndicate_Admin
Administrator
Administrator

@Ahmed-Elfeel Muchísimas gracias por tu ayuda, las cosas empiezan a aclararse... ¿podrías ayudarme a pensar en cómo crearía esta regla?

¿Cómo crearía este RLS dinámico... La persona solo puede ver estos coli-codcusto (tabla dcentrodecusto (tabla diensao)) [COLI-CODCUSTO] == "1-1.000010" || [COLI-CODCUSTO] == "2-1.000012"

en la tabla de Dfornecedor, esta regla [CODCFO] <> "0009789"

en la tabla de dMedContratos (tabla de dimensiones), esta regla [Contrato] == "" (es decir, no quiero que aparezca nada de esta tabla)

en la tabla fAjusteGerencial (tabla de hechos), esta regla VAR TI = RELATED(dCentrodeCusto[NOME]) IN {"TECNOLOGIA DA INFORMAÇÃO"} VAR ContaValida = NOT ( [Conta] IN { "Salários E Ordenados", "Hora Extra", "Encargos Trabalhistas", "Rescisões E Indenizações", "Prêmios E Bonificações" } ) RETURN (TI & ContaValida)

en la tabla fBalance (tabla de hechos), esta regla VAR TI = RELACIONADO(dCentrodeCusto[NOME]) EN {"INFORMATION TECHNOLOGY"} VAR ValidAccount = NOT ( RELATED('dC Account'[Cuentas de Gestión]) IN { "Salarios y Salarios", "Horas Extra", "Cargos Laborales", "Despidos y Compensaciones", "Bonificaciones y Bonificaciones" } ) VAR Initial Excharge = NOT ( fBalance Sheet[COMPLEMENT2] = {"JOAO DA SILVA"} ) DECLARACIÓN (IT & & ValidAccount & Initial Gastense)

en la tabla de fMedidas (tabla de hechos), esta regla [CODCCUSTO] <> "" en la tabla fPartida (tabla de hechos), esta regla [IDPARTIDA] == "195X195X195" (es decir, no quiero que vea nada)

en la tabla fpitempartida (tabla de hechos), esta regla [CHAPA] == "195X195X195" (es decir, no quiero que vea nada)

en En la tabla 'ftmovitens' (tabla de hechos), esta regla: 'VAR TI = RELATED(dCentrodeCusto[NOME]) IN {"TECNOLOGIA DA INFORMAÇÃO"} VAR ContaValida = NOT ( RELATED('dC Conta'[Contas Gerenciais]) IN { "Salários E Ordenados", "Hora Extra", "Encargos Trabalhistas", "Rescisões E Indenizações", "Prêmios E Bonificações" } ) RETURN (TI & & ContaValida)' Bonus" } ) RETURN (TI & ContaValida)

y en la tabla fvalorçado (tabla de hechos), esta regla VAR TI = RELATED(dCentrodeCusto[NOME]) IN {"INFORMATION TECHNOLOGY"} VAR ContaValida = NOT ( [Conta] IN { "Salarios y Sueldos", "Horas Extra", "Cargos Laborales", "Despidos y Compensaciones", "Bonos y Bonificaciones" } ) RETORNO (TI & & ContaValida)

@PedroModa,

Por supuesto, aquí tienes una solución sencilla y clara paso a paso que puedes hacer:


El primer paso es crear una tabla de seguridad llamada UserSecurity con todos los permisos de usuario así:

UserEmailCostCenter
manager@powerbi.comCC01
manager@powerbi.comCC02
Hasta que llegues al final (25)etcetera

Segundo Paso es poner reglas RLS para cada tabla

  • dCentrodeCusto (dimensión):
[COLI-CODCUSTO] IN VALUES(UserSecurity[CostCenter])
  • dProveedor (dimensión):
NOT([CODCFO] IN VALUES(UserSecurity[RestrictedSupplier]))
  • dMedContratos (ocultar toda la mesa):
[Contrato] IN {""}  // Or use FALSE() to hide everything
  • Ajuste fgestional (tabla de hechos):
VAR TI = RELATED(dCentrodeCusto[NOME]) = "TECNOLOGIA DA INFORMACAO"
VAR ValidAccount = NOT([Conta] IN { 
    "Salários E Ordenados", 
    "Hora Extra", 
    "Encargos Trabalhistas", 
    "Rescisões E Indenizações", 
    "Prêmios E Bonificações" 
})
RETURN TI && ValidAccount
  • fBalance (tabla de hechos):
VAR TI = RELATED(dCentrodeCusto[NOME]) = "INFORMATION TECHNOLOGY"
VAR ValidAccount = NOT(RELATED('dC Account'[Management Accounts]) IN { 
    "Salaries and Wages", 
    "Overtime", 
    "Labor Charges", 
    "Terminations and Compensation", 
    "Bonuses and Bonuses" 
})
VAR InitialExpense = NOT([COMPLEMENT2] = "JOAO DA SILVA")
RETURN TI && ValidAccount && InitialExpense
  • fPartida and fpitempartida (hide everything):
FALSE()  // Hides all rows
  • ftmovitens y fvalorcado (Usa la misma lógica que fAjusteGerencial pero adapta los nombres de las columnas)

El tercer y último paso es añadir esto a la tabla de UserSecurity:

[UserEmail] = USERPRINCIPALNAME()

Espero que esto te resulte útil porque ha tardado demasiado y si necesitas ayuda, dímelo y perdón por la demora 🫡❤️

Syndicate_Admin
Administrator
Administrator

@Ahmed-Elfeel

¡Muchas gracias! He visto algo de contenido sobre RLS dinámico, pero como nunca he trabajado con él antes, todavía tengo muchas preguntas... Una de ellas es, por ejemplo, si este gestor puede ver 25 centros de costes, ¿debería crear 25 filas en la tabla para este gestor? Por ejemplo:

manager@powerbi.com | Centro de Costes 1

manager@powerbi.com | Centro de Costes 2

manager@powerbi.com | Centro de Costes 3

¿Y así sucesivamente?

Y en casos en los que, por ejemplo, quería "ocultar" la información en una columna de UNA TABLA para esta regla:

manager@powerbi.com | Centro de Costes 2

la tabla de transacciones, por ejemplo, quiero ocultar la información para el proveedor 3...

¿Cómo podría hacerlo? Esto me resulta muy confuso. ¿Debería manejar esto en la propia tabla o debería hacerlo de forma más "detallada" dentro de Power BI?

@PedroModa,

Así que vamos a hacer preguntas una por 😅❤️ una

Primera pregunta

Si este gestor puede ver 25 centros de costes, ¿deberías crear 25 filas en la tabla para este gestor?

  • Así que sí, exactamente crea 25 filas separadas exactamente así:
NombrePrincipalUsuarioPrincipalCostCenter
manager@powerbi.comCC01
manager@powerbi.comCC02
manager@powerbi.comCC03
manager@powerbi.comhasta alcanzar el máximo (25)

Segunda pregunta

¿Cuál es la regla RLS para esta estructura?

  • Solo una regla sencilla en tu tabla de seguridad:
[UserPrincipalName] = USERPRINCIPALNAME()

Tercera pregunta

¿Cómo oculto a un proveedor en UNA sola tabla?

  • Así que para esta pregunta hay dos enfoques que podrías probar (los más cómodos para ti)\
  • La primera es añadir columnas de restricción a tu tabla principal de seguridad:
NombrePrincipalUsuarioPrincipalCostCenterProveedor Restringido
manager@powerbi.comCC02Supplier3

Y la regla RLS para esto:

AND(
    [CostCenter] IN VALUES(SecurityTable[CostCenter]),
    NOT([Supplier] IN VALUES(SecurityTable[RestrictedSupplier]))
)
  • La segunda es crear tablas dedicadas para diferentes tipos de restricciones:
NombrePrincipalUsuarioPrincipalProveedor Restringido
manager@powerbi.comSupplier3

Y la regla RLS para esta tabla es:

// Main cost center access
[CostCenter] IN VALUES(UserCostCenterAccess[CostCenter])

// Supplier restrictions  
NOT([Supplier] IN VALUES(UserSupplierRestrictions[RestrictedSupplier]))

Finalmente

  • Siempre deberías manejar esto en las tablas RLS (no dentro de los gráficos de Power BI ni en DAX complejos).

si este post ayuda, agradecería un pulgar arriba y marcáralo como la solución para ayudar a los demás miembros a encontrarla más rápido.
Syndicate_Admin
Administrator
Administrator

@PedroModa,

Espero que hoy ☺️❤️ estés bien

Así que el problema probablemente sea la naturaleza aditiva del RLS cuando un usuario está asignado a múltiples roles; la pertenencia de tu usuario a 25 roles significa que Power BI debe combinar los filtros de todos ellos, lo que puede afectar gravemente al rendimiento (Las condiciones de OR dentro de cada regla complican aún más la lógica de filtrado)

¿Qué deberías hacer para resolvereste problema?... Aquí tienes un enfoque que puedes probar:

Primer enfoque: (escalabilidad a largo plazo y para grandes organizaciones)

  • Crea una tabla central que enlace a los usuarios con sus centros de costes (puede ser una hoja de Excel, una tabla de base de datos o una lista de SharePoint que importes)

  • Uso un rol en el RLS con:

[Username] = USERNAME()
  • Relaciona esta tabla con tu modelo de datos (los filtros se propagan automáticamente)

Segundo enfoque (Solución rápida)

  • Fusiona 25 roles en 1-3 roles más amplios

  • Sustituir múltiples condiciones OR por una sola cláusula IN
  • Reducir la sobrecarga de filtrado aditivo

Tercer enfoque

  • Combina RLS con filtros a nivel de página
  • Utiliza tablas resumen para obtener opiniones directivas
  • Implementa RLS con moderación

Enfoque Final (Optimización Técnica)

  • Convertir códigos de texto en IDs enteros
  • Asegurar relaciones de una sola dirección

  • Usa tablas importadas en lugar de consulta directa
si este post ayuda, agradecería un pulgar arriba y marcáralo como la solución para ayudar a los demás miembros a encontrarla más rápido.
Syndicate_Admin
Administrator
Administrator

@PedroModa

Gracias por ponerte en contacto con la comunidad del Foro Microsoft Fabric.

@amitchandak Muchas gracias por tus aportaciones.

Espero que la información proporcionada por los usuarios haya sido útil. Si aún tienes preguntas, no dudes en contactar con la comunidad.

Syndicate_Admin
Administrator
Administrator

@PedroModa , cuando usas más de un rol, se tratan como condiciones de quirófano. Por lo tanto, necesitamos fusionar esos roles en un solo rol. Esto significa que debes combinar las condiciones en un solo rol si quieres que funcionen como condición AND

Helpful resources

Announcements
November Power BI Update Carousel

Power BI Monthly Update - November 2025

Check out the November 2025 Power BI update to learn about new features.

Fabric Data Days Carousel

Fabric Data Days

Advance your Data & AI career with 50 days of live learning, contests, hands-on challenges, study groups & certifications and more!

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Kudoed Authors