在安全谓词中通过 SYSTEM_USER() 过滤避免索引并导致性能降低

问题描述

我们在多租户应用程序中使用行级安全性进行过滤。 直到现在我们的谓词函数看起来像这样(按tenantId过滤):

CREATE FUNCTION [Security].[FN_SecurityPredicate](@TenantId uniqueidentifier)
 RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN
       SELECT 1 AS Result
       WHERE CAST(SESSION_CONTEXT(N'TenantId') AS uniqueidentifier) = @TenantId
GO

在某些情况下,我们希望从所有租户获取数据,因此我们最近决定通过使用名为 user_datareader 的特殊用户执行查询来实现此目的。使用此用户执行 select 语句时,结果应避免租户检查,并返回所有用户的数据。谓词现在如下所示:

CREATE FUNCTION [Security].[FN_SecurityPredicate](@TenantId uniqueidentifier)
 RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN
       SELECT 1 AS Result
       WHERE CAST(SESSION_CONTEXT(N'TenantId') AS uniqueidentifier) = 

@TenantId
 OR SYstem_USER = 'user_datareader'
    GO

谓词工作正常。问题是执行计划现在已更改,并且在谓词更改之前使用的所有索引现在都未使用。因此,所有查询都变得非常缓慢。我不明白为什么 SYstem_USER() 检查更改特定表上的执行计划。

有谁知道如何将这个谓词更改为仍然使用索引的方式?或者我们做错了什么,SYstem_USER 检查应该在行级安全机制中应用不同?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)