存储过程 - 函数性能差异

12 浏览
0 Comments

存储过程 - 函数性能差异

我有一个表值函数,里面有相当多的代码,执行多个连接查询,调用子函数并返回结果集。在开发这个函数的过程中,有一段时间,当执行函数时,性能下降了。通常情况下,它不应该超过1秒,但开始需要大约10秒。我尝试了一些关联和索引的调整,但没有什么显著变化。

经过一段时间的变更和研究后,我想以另一种方式查看结果。我创建了完全相同的代码和参数的存储过程,然后执行了存储过程。哇!它只需要不到1秒的时间。相同的代码作为函数需要大约10秒的时间。

我真的无法理解这到底是怎么回事,而且我没有时间进行更多的研究。出于某些原因,我需要它作为一个函数,但我不知道该怎么办。我以为我可以将其创建为存储过程,然后在函数内调用它,但后来我意识到对于函数来说这是不可能的。

我想从这里听听专家们的好意见和建议。

提前谢谢。

附:我没有在这里添加任何代码,因为代码格式不好,而且相当混乱。如果有人感兴趣,我可以分享代码。服务器是SQL 2014企业版64位。

编辑:我之前看到可能有相似的问题,但它没有满足我的需求,因为我的问题特别涉及性能问题。其他问题有很多关于存储过程和函数之间一般区别的答案。我想更明确地了解可能与性能相关的差异。

0
0 Comments

存储过程和函数在性能方面的差异是有原因的。首先,当你开始编写函数时,很可能会反复使用相同的参数来测试它,直到它能正确运行。这样会启用页面缓存,使得SQL Server将相关的数据存储在内存中。而函数本身不会缓存执行计划,随着数据的增加,生成执行计划的时间会变长。可以使用SET STATISTICS TIME ON来查看查询编译时间和执行时间。此外,函数只能使用表变量,并且没有统计信息可供使用,这可能导致后续的连接决策变得糟糕。

有些人更喜欢使用表值函数,因为它们更容易进行查询。相比于创建临时表,执行存储过程然后从临时表中筛选数据,可以直接在表值函数上使用SELECT语句并添加条件进行筛选。如果代码的性能至关重要,可以将其转换为存储过程。

最后,上述问题中的SQL Server执行时间显示了执行时间与编译时间的差异,这是因为函数未缓存执行计划,而存储过程则会缓存执行计划,从而提高执行效率。

存储过程和函数在性能方面的差异主要体现在执行计划的缓存和使用的数据类型上。为了解决这些问题,可以考虑将性能关键的代码转换为存储过程,并优化查询条件和数据类型的选择,以提高执行效率。

0