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) 

首先, DataAccessSystemDataAccess默认为DataAccessKind.None ,因此将它们显式设置为DataAccessKind.None ,虽然这是一个好的做法,但不应该有任何明显的区别。

还需要设置另外两个属性: IsDeterministicIsPrecise 。 这些属性是查询优化程序使用的元数据,默认情况下均为false 。 因此,最好将它们中的一个或两个设置为true(当然,假设设置准确地反映了该特定函数内的代码)。

  • 确定性意味着保证相同的输入具有相同的输出。 因此,如果您的函数将始终为特定输入集返回相同的值,则它是确定性的,应标记为IsDeterministic = true
  • 如果不使用任何浮点(即DoubleSingle )值(即T-SQL术语中的FLOATREAL ),则可以设置IsPrecise = true

SqlFunction属性应如下所示:

 [Microsoft.SqlServer.Server.SqlFunction(SystemDataAccess = DataAccessKind.None, DataAccess = DataAccessKind.None, IsDeterministic = true, IsPrecise = true)] public static SqlString MyUDF(SqlString data) 

更新:

  • 可能需要的另一个项是包含此方法的程序集具有SAFEPERMISSION_SET
  • 为了使UDF在并行执行计划中工作,可能不需要IsPrecise属性的SqlFunction属性设置为true

它可能不是CLR UDF的问题,而是SQL Server的查询计划决策。 您可以使用OPTION (QUERYTRACEON 8649)强制执行并行计划,如此处所述。