使 SQL 服务器 CLR 聚合类似于本机聚合

Make SQL Server CLR aggregate similar to native aggregates

我正在比较我的自定义 CLR 聚合与 AVG (SQL Server 2017)。我的查询是:

  SELECT groupId, Helpers.CustomCLR(value)
  FROM table
 group by groupId

  SELECT groupId, AVG(value)
  FROM table
 group by groupId

而 CLR 是

    [Serializable]
    [SqlUserDefinedAggregate(
        Format.Native, //use clr serialization to serialize the intermediate result  
        IsInvariantToNulls = true, //optimizer property  
        IsInvariantToDuplicates = false, //optimizer property  
        IsInvariantToOrder = true)
]
    [StructLayout(LayoutKind.Sequential)]
    public class CustomCLR
    {
        float a = 2;
        public void Init()
        {
        }

        public void Accumulate(SqlSingle value)
        {
        }

        public void Merge(CustomCLR other)
        {
        }

        public double? Terminate()
        {
            return a;
        }
    }

不过,执行计划完全不同。 CLR 查询执行行模式排序,AVG 查询执行批处理模式哈希匹配。如何使 CLR 聚合表现得像 AVG 一样?

内置函数和 SQLCLR 用户定义聚合函数 (UDA) 之间肯定存在一些不幸的差异。其中之一应该是SQLCLR不能做批处理模式。我看看能不能找到这方面的权威参考。

另一个区别是 SQLCLR UDA 不支持 HashAggregate 运算符,导致:

CLR Aggregate performs an expensive sort

我刚刚在 SQL Server 2017 CU 12 和 SQL Server 2019 CTP 2.2 中再次测试,它仍然是一个问题。请参阅 Bob Beauchemin 于 2010 年 12 月 9 日星期四发表的 post(在该链接的论坛帖子中),了解一些建议的解决方法。

也请支持 Bob 的增强请求以允许 SQLCLR UDA 使用 OPTION(HASH GROUP):

Allow OPTION(HASH GROUP) with SQLCLR UDAs