我发现本地计算机上的查询计划和 Azure SQL 上的查询计划之间存在奇怪的差异。我正在尝试实现行级安全性,其中我从 SESSION_CONTEXT 读取用户标识符,然后在 TVF 中检查用户是否具有访问权限。
在我的本地计算机上 - SQL Server 2019 Developer Edition,兼容级别 150 的数据库,查询计划符合预期。但是当我在兼容级别为 150 的 Azure DB 上运行它时,我只能获得带有NonParallelPlanReason="NonParallelizableIntrinsicFunction"
. 我尝试了超大规模数据库以及弹性池中的数据库,两个数据库的结果相同。
您可以使用以下代码重现该内容:
CREATE TABLE Users (
UserIdentifier nvarchar(100) PRIMARY KEY CLUSTERED
)
INSERT INTO Users (UserIdentifier) VALUES ('MyUserIdentifier')
CREATE TABLE TableWithRLS (
Id int NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
DataColumn nvarchar(100) NULL
)
INSERT INTO TableWithRLS (DataColumn)
SELECT TOP 10000000 A.[name] FROM sys.all_columns AS A
CROSS JOIN sys.all_columns AS B
CROSS JOIN sys.all_columns AS C …
Run Code Online (Sandbox Code Playgroud) performance sql-server parallelism azure-sql-database row-level-security
我发现下面的查询在运行相同兼容性级别、相同设置选项等的两个 Azure 超大规模数据库上返回不同的结果。
IF CAST(ServerProperty('Edition') AS nvarchar(128)) = 'SQL Azure' BEGIN
SELECT 1
END
IF ServerProperty('Edition') = 'SQL Azure' BEGIN
SELECT 2
END
IF 'SQL Azure' = ServerProperty('Edition') BEGIN
SELECT 3
END
Run Code Online (Sandbox Code Playgroud)
在一个数据库上,它仅返回 1,在其他数据库上,它返回 1,2 和 3。
我调查了根本原因,似乎是由数据库的排序规则不同引起的。
对于以下查询:
SELECT SQL_VARIANT_PROPERTY(ServerProperty('Edition'), 'Collation')
SELECT name, collation_name, compatibility_level FROM sys.databases
Run Code Online (Sandbox Code Playgroud)
数据库只返回一行,结果是:
-----------------------------
SQL_Latin1_General_CP1_CI_AS
name collation_name compatibility_level
------------ -------------------------------- -------------------
master SQL_Latin1_General_CP1_CI_AS 140
my_database SQL_Latin1_General_CP850_CI_AS 150
Run Code Online (Sandbox Code Playgroud)
数据库返回1,2,3的结果是:
-----------------------------
SQL_Latin1_General_CP1_CI_AS
name collation_name compatibility_level
------------ -------------------------------- -------------------
master SQL_Latin1_General_CP1_CI_AS 140
my_database SQL_Latin1_General_CP1_CI_AS 150
Run Code Online (Sandbox Code Playgroud)
因此,不进行强制转换的简单比较是sql_variant …