sql-server - 使用 CLR 集成表函数进行高效交叉应用

标签 sql-server sqlclr cross-apply

在 SQL Server 中,我有一个基于 CLR 集成的表值函数 GetArchiveImages。我这样调用它:

SELECT ...
FROM Items
CROSS APPLY GetArchiveImages(Items.ID) AS archiveimages
WHERE ...

问题是每次单独调用该函数都会产生开销。

如果它可以一次与整个表连接,开销会非常小,但由于它为每一行调用一次,因此开销会随着行数的增加而增加。

我不使用存储过程,因为存储过程返回的表不能与任何东西连接(据我所知)。

是否有一种有效的方法来批量连接表和存储过程或函数的结果,而不是逐行连接?

最佳答案

由于 GetArchiveImages 的结果取决于 Items.ID SQL Server 必须为每个项目调用该函数,否则您将无法获得正确的结果。

SQL Server 唯一可以“分解”的函数是 T-SQL 内联表值函数。因此,如果您可以将 CLR 重写为 ITVF,您将获得更好的性能。

根据我的经验,调用 CLR 函数的开销并不大。您更有可能在查询的其他地方遇到问题。例如,SQL Server 不知道该函数将返回多少行,只是假设它是一个(对于每次调用)。这可能会导致在优化过程中其他地方做出错误的决定。


更新:

SQL Server 不允许在 CLR 类中保留静态非常量数据。有一些方法可以欺骗系统,例如通过创建静态最终集合对象(您可以从静态集合中添加和删除项目),但是,出于稳定性原因,我建议不要这样做。

在您的情况下,创建一个使用某种(数据库或文件系统)触发器或按计划自动刷新的缓存表可能是有意义的。无需调用该函数,您只需加入该表即可。

关于sql-server - 使用 CLR 集成表函数进行高效交叉应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14340795/

相关文章:

sql - 更新闭包表的最佳方法是什么?

c# - 在T-SQL中处理CLR存储过程的多个结果

c# - 是否有更好的方法在 CLR 中验证 SqlXml?

使用带有删除语句的交叉应用的 T-SQL

mysql - 需要帮助将以下 SQL 查询转换为 MySQL 而无需交叉应用方法

c# - 由于查询找不到我所要求的值的单个实例而出现错误,我该如何解决这个问题?

sql-server - GO 和 BEGIN...END 之间的区别

sql - TSQL:是否有办法限制返回的行并计算没有限制的返回总数(不将其添加到每一行)?

sql - SQL Server APPLY AND JOIN 关键字指南

java - JOOQ Cast String to Enum 使用转换器内联