SQL Server表值函数执行代码

时间:2017-07-26 10:40:51

标签: sql sql-server tsql user-defined-functions row-level-security

基于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。

1 个答案:

答案 0 :(得分:2)

最好的方法是在关闭策略然后打开的情况下查看执行计划。你会看到它做的额外工作。您正在添加另一个表来进行查询,因此它类似于进行连接但可能更有效。

要回答您的问题,如果您在策略开启时看到在计划中添加了嵌套循环,那么它是逐行的Nested Loops

也可以使用DBCC SHOW_STATISTICS来查看资源命中。对于较小的桌子,我从未看到任何明显的性能命中,<类似实现中的100,000行。

我之前发现此链接非常有用。

https://www.mssqltips.com/sqlservertip/4005/sql-server-2016-row-level-security-limitations-performance-and-troubleshooting/