存储过程 - 函数性能差异

Posted

技术标签:

【中文标题】存储过程 - 函数性能差异【英文标题】:stored procedure - function performance difference 【发布时间】:2015-07-02 23:27:23 【问题描述】:

我有一个表值函数,其中包含相当多的代码,执行多个连接选择并调用子函数并返回结果集。在此功能的开发过程中,在某些时候,我在执行该功能时遇到了性能下降。通常它不应该花费超过 1 秒,但它开始需要大约 10 秒。我玩了一点连接和索引,但没有发生太大变化。 经过一段时间的改变和研究,我想用另一种方式看到结果。我创建了与存储过程具有相同参数的完全相同的代码。然后我执行了 sp。繁荣!它需要不到 1 秒。使用函数执行相同的确切代码大约需要 10 秒。

我真的无法弄清楚这到底是怎么回事,我没有时间做更多的研究。由于某些原因,我需要它作为一个函数,但我现在不知道该怎么做。我以为我可以将它创建为 proc,然后在函数中调用它,但后来我意识到不可能为函数这样做。

我想在这里听取专家的一些好的意见和建议。 提前致谢

ps:我没有在这里添加任何代码,因为代码格式不好而且很脏。如果有人感兴趣,我会分享它。服务器是 sql 2014 企业 64 位 编辑:我之前看到过可能重复的问题,但它并没有让我满意,因为我的问题专门针对性能影响。另一个问题有很多关于过程和功能之间的一般差异的答案。我想更清楚地说明可能与性能相关的差异。

【问题讨论】:

存储过程缓存了执行计划,而用户定义的函数没有,因此存储过程的性能更好。谷歌SQL Server Stored procedure execution plan,你会学到很多东西。 Functions vs Stored Procedures 的可能重复项 正如@M.Ali 提到的,多语句表函数不存储执行计划,而存储过程可以。查看Functions vs Stored Procedures中的链接和讨论主题 为了表现良好,您需要将其重构为内联表值函数,但根据您的描述,这似乎不是一个选项。内联 TVF 可以扩展和优化,但不能扩展和优化多语句,此外,它们没有统计信息,因此查询优化器很难为更大的数据集制定一个好的计划。 【参考方案1】:

这些是我的经验的不同之处:

当您第一次开始编写函数时,您可能会使用相同的参数一次又一次地运行它,直到它正常工作。这将启用页面缓存,其中 SQL Server 将相关数据保存在内存中。 函数不缓存其执行计划。随着您添加更多数据,制定计划需要更长的时间。 SET STATISTICS TIME ON 查看查询编译时间与执行时间。 函数只能使用表变量,并且没有关于这些变量的统计信息。这可能会在以后做出一些可怕的JOIN 决定。

有些人更喜欢表值函数,因为它们更容易查询:

SELECT * FROM fcn_myfunc(...) WHERE <some_conditions>

不创建临时表,而是执行存储过程,然后过滤掉该临时表。如果您的代码对性能至关重要,请将其转换为存储过程。

【讨论】:

SQL Server 解析和编译时间:CPU 时间 = 0 毫秒,已用时间 = 0 毫秒。 SQL Server 执行时间:CPU 时间 = 0 毫秒,经过时间 = 0 毫秒。 (受影响的 5 行)SQL Server 执行时间:CPU 时间 = 12531 毫秒,经过时间 = 13106 毫秒。这有意义吗?

以上是关于存储过程 - 函数性能差异的主要内容,如果未能解决你的问题,请参考以下文章

存储过程 - 函数性能差异

视图和存储过程之间是不是存在性能差异

循环与调用函数的 SQL 性能差异

存储过程和函数

Sqlserver中存储过程,触发器,自定义函数

差异备份的存储过程