【问题标题】:SQL Server CLR UDF Parallelism reduxSQL Server CLR UDF 并行还原
【发布时间】:2014-07-13 12:29:22
【问题描述】:

我研究 SQL Server CLR UDF 和并行性已经有一段时间了。普遍的共识似乎是,在 SQL Server 2008 及更高版本中,带有DataAccessKind.None 的标量值 CLR UDF 应该允许并行执行。

但是,当我在 SQL Server 2012 的视图中使用我的标量值 UDF 时,它仍然会终止连接等中的并行执行。

我需要在我的 C# 代码或 T-SQL UDF 定义中添加什么特别的东西来表明并行执行是安全的吗?

谢谢。

【问题讨论】:

  • 根据版主的建议,我提供了一个链接,指向我之前发布的关于该主题的帖子:social.msdn.microsoft.com/Forums/sqlserver/en-US/…
  • 您是否在 UDF 中做任何事情来阻止它被认为是确定性的?如果不是,那么您是否在SqlFunction() 属性中指定IsDeterministic = trueIsDeterministic 默认为假。 IsPrecise 也是如此。
  • 如果设置IsDeterministic 和/或IsPrecise 可以解决问题(假设您没有在函数中执行任何操作来阻止将它们设置为true),那么我将在此处发布答案以及跟进那个 MSDN 论坛。
  • 我很确定我的 UDF 是确定性的。你能给我一个不是确定性的例子吗? (除此之外,比如 RAND()、@@IDLE 等)
  • @srutzky - 我也在想同样的事情。我将创建一个新线程并在此处发布链接。谢谢!

标签: c# sql-server parallel-processing sqlclr


【解决方案1】:

根据问题的第一条评论中链接到的 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)

更新:

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

【讨论】:

    【解决方案2】:

    这可能不是 CLR UDF 的问题,而是 SQL Server 的查询计划决策。您可以按照here 的说明使用OPTION (QUERYTRACEON 8649) 强制执行并行计划。

    【讨论】:

    • 嗨,迈克尔。如果 CLR UDF 被标记为 DataAccessKind.None(或至少 not 被标记为 DataAccessKind.Read,因为 None 是默认值)和 IsDeterministic = true 并且仍然永远不会获得并行计划,那么它可能是别的东西,在这种情况下 TraceFlag 可能会有所帮助。但是UDF确实需要标记为IsDeterministic = true
    猜你喜欢
    • 1970-01-01
    • 2010-09-18
    • 2011-07-27
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2012-09-18
    • 1970-01-01
    相关资源
    最近更新 更多