如何解决如何在使用 SQLCLR 用户定义聚合函数 (UDA)
我们在使用 sqlCLR 用户定义聚合函数 (UDA) 时发现了性能问题,
这是我们的场景: 我们需要计算 2 列:key 和 value,其值如下:
键 | 价值 | |
---|---|---|
Row_1 | a/b/c/d/e | 1/2/3/2/1 |
Row_2 | a/b/c/d/e | 2/0/1/2/3 |
Row_3 | a/b/c/d/e | 2/3/4/1/2 |
我们需要一个聚合函数来获取每个指标的总和,在上面的例子中,我们想要得到这样的结果:
键 | 价值 | |
---|---|---|
结果 | a/b/c/d/e | 5/5/8/5/6 |
没有我们可以使用的本机聚合函数来获得这种结果,因此我们使用 sqlCLR UDA 来实现这种结果。我们发现当 sqlCLR UDA 与 GROUP BY 子句一起使用时,该 UDA 的性能很差。
经过一番调查,我们发现原因如下:
- 当我们使用 sqlCLR UDA 时,必须使用 StreamAggregate 操作,并且会引入昂贵的排序运算符,从而降低 UDA 的性能。
- 当我们使用 sqlCLR UDA 时,只能使用行模式来计算排序和聚合运算符中的结果。
所以,我的问题是:
- 用户是否有机会在使用用户定义的聚合函数时强制 sql Server 使用哈希聚合运算符而不是流运算符?
- 在使用用户定义的聚合函数时,用户是否有机会使用排序运算符?
- 在使用用户定义的聚合函数时,用户是否有机会使用批处理模式?
解决方法
当数据库违反第一范式时,您将永远不会获得任何性能......因为这导致没有关系数据库......并且关系引擎专门设计用于快速处理关系数据而不是非关系数据。
这不是 UDA 性能的问题,而是您的设计导致严重的反性能问题。
第一范式表示表中的列必须始终具有单个(标量)值。您放置了一个违反第一范式的值列表。
只需通过添加子表重新设计数据库并将键和值放入该子表中,您就会有性能!
你可以试试这个:
CREATE TABLE T_CHILD
(ID_CHILD INT IDENTITY PRIMARY KEY,ID_ROW VARCHAR(32),--REFERENCES T_FATHER (ID_ROW),KEY_CHILD VARCHAR(16),VALUE_CHILD INT);
GO
INSERT INTO T_CHILD
SELECT ID_ROW,k.value,V_EMP.value
FROM T_FATHER
OUTER APPLY STRING_SPLIT([key],'/') AS k
OUTER APPLY STRING_SPLIT([value],'/') AS v;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。