SQL Server CLR UDF Parallelism redux
我一直在研究SQL Server CLR UDF和并行性。 普遍的共识似乎是在SQL Server 2008及更高版本中,带有DataAccessKind.None
的标量值CLR UDF应该允许并行执行。
但是,当我在SQL Server 2012的视图中使用我的标量值UDF时,它仍然会杀死连接中的并行执行等。
有什么特别的东西需要添加到我的C#代码或T-SQL UDF定义中,以表明它对于并行执行是安全的吗?
谢谢。
根据与该问题的第一条评论相关联的MSDN论坛,您的C#代码大致从以下开始:
[Microsoft.SqlServer.Server.SqlFunction()] public static SqlString MyUDF(SqlString data)
并根据问题,您已添加DataAccessKind.None
使其成为:
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.None)] public static SqlString MyUDF(SqlString data)
首先, DataAccess
和SystemDataAccess
默认为DataAccessKind.None
,因此将它们显式设置为DataAccessKind.None
,虽然这是一个好的做法,但不应该有任何明显的区别。
还需要设置另外两个属性: IsDeterministic
和IsPrecise
。 这些属性是查询优化程序使用的元数据,默认情况下均为false
。 因此,最好将它们中的一个或两个设置为true(当然,假设设置准确地反映了该特定函数内的代码)。
- 确定性意味着保证相同的输入具有相同的输出。 因此,如果您的函数将始终为特定输入集返回相同的值,则它是确定性的,应标记为
IsDeterministic = true
。 - 如果不使用任何浮点(即
Double
或Single
)值(即T-SQL术语中的FLOAT
或REAL
),则可以设置IsPrecise = true
。
SqlFunction属性应如下所示:
[Microsoft.SqlServer.Server.SqlFunction(SystemDataAccess = DataAccessKind.None, DataAccess = DataAccessKind.None, IsDeterministic = true, IsPrecise = true)] public static SqlString MyUDF(SqlString data)
更新:
- 可能需要的另一个项是包含此方法的程序集具有
SAFE
的PERMISSION_SET
。 - 为了使UDF在并行执行计划中工作,可能不需要将
IsPrecise
属性的SqlFunction
属性设置为true
。
它可能不是CLR UDF的问题,而是SQL Server的查询计划决策。 您可以使用OPTION (QUERYTRACEON 8649)
强制执行并行计划,如此处所述。