Цель
Я реализую безопасность на уровне строк (RLS) на Azure Синапс на основе аутентификации Active Directory (AD). Идея состоит в том, что клиенты, добавленные в security_group_A_access
, имеют доступ ко всем строкам MY_TABLE со столбцом CATEGORY = 'A'
. См. Код ниже.
Проблемы
IS_MEMBER
Функция вызывается один раз для каждой строки, в результате чего запрос SELECT DISTINCT CATEGORY FROM MY_TABLE
выполняется более 3 минут вместо 1 секунды. Кажется, что это общая проблема . - Даже при жестком кодировании условия
fn_predicate
с WHERE CATEGORY = 'A'
(удаление IS_MEMBER
invocation) запросы становятся медленнее. Таблицы RLS имеют до миллиарда строк и используются для отчетов Power BI, поэтому для них очень важно производительность / время отклика.
Вопросы
- Есть ли способ вызвать
IS_MEMBER
функцию не чаще, чем есть группы безопасности? Значит ли это как-то кешировать результат или сохранить его в глобальной переменной, et c. - Является ли RLS общий подход для таблицы с миллиардами строк с критической производительностью? Или это обычная практика - создавать представление для каждой группы безопасности AD?
Код
CREATE SCHEMA [security]
GO
CREATE FUNCTION [security].[fn_predicate](@category_column as varchar(50))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS fn_predicate
WHERE IS_MEMBER(CONCAT('security_group_', @category_column, '_access')) = 1
GO
GRANT SELECT ON [security].[fn_predicate] TO security_group_A_access
GRANT SELECT ON [security].[fn_predicate] TO security_group_B_access
GO
CREATE SECURITY POLICY MY_TABLE_FILTER
ADD FILTER PREDICATE [security].[fn_predicate]([CATEGORY])
ON [dbo].[MY_TABLE]
WITH (STATE = ON)
GO
PS
Я могу перефразировать этот вопрос следующим образом: - Есть ли варианты лучше, чем 1-й?
Три возможных подхода:
Создать представление для CATEGORY
и ограничить каждую группу для отдельного просмотра.
- Плюсы: На производительность
MY_TABLE
для отчетов PBI не влияет - Минусы: Количество просмотров. Предположим, у вас есть категории A, B, C, D, E. Чем вам нужно 5 просмотров. Что если есть пользователь, который состоит из групп A и C?
Применить RLS поверх MY_TABLE
.
- Плюсы: Мой текущий подход. Прост в реализации, без дополнительных таблиц и представлений. Масштабируемый, в случае большего количества КАТЕГОРИЙ, будут добавлены группы или правила.
- Минусы: См. Раздел «Проблемы». На производительность
MY_TABLE
практически не влияют и не приемлемы
Гибридный подход. Создайте одиночный MY_TABLE_VIEW
и примените RLS поверх представления.
- Плюсы: все преимущества второго варианта плюс производительность
MY_TABLE
для отчетов PBI не влияют . - Минусы: еще нужно решить
IS_MEMBER
проблему с производительностью, см. 1-й пункт в разделе «Проблемы».