基于Row level security我创建了一个表值函数:
CREATE FUNCTION Security.userAccessPredicate(@ValueId int)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT 1 AS accessResult
WHERE @ValueId =
(
SELECT Value
FROM dbo.Values
WHERE UserId = CAST(SESSION_CONTEXT(N'UserId') AS NVARCHAR(50))
) OR NULLIF(CAST(SESSION_CONTEXT(N'UserId') AS nvarchar(50)),'') IS NULL
);
CREATE SECURITY POLICY Security.userSecurityPolicy
ADD FILTER PREDICATE Security.userAccessPredicate(ValueUd) ON dbo.MainTable
让我们说MainTable
包含数百万行。 userAccessPredicate
是否为每一行独立计算SELECT Value FROM dbo.Values
?如果是这样,我猜它是无效的。如何检查执行表值函数时生成的确切代码? SQL Server Profiler不是因为我使用的是Azure DB。
我正在使用SQL Server 2016 Management Studio。
答案 0 :(得分:2)
最好的方法是在关闭策略然后打开的情况下查看执行计划。你会看到它做的额外工作。您正在添加另一个表来进行查询,因此它类似于进行连接但可能更有效。
要回答您的问题,如果您在策略开启时看到在计划中添加了嵌套循环,那么它是逐行的Nested Loops
也可以使用DBCC SHOW_STATISTICS来查看资源命中。对于较小的桌子,我从未看到任何明显的性能命中,<类似实现中的100,000行。
我之前发现此链接非常有用。