2017-06-15 98 views
0

问题是:可以使用内联表值函数(ITVF)来封装和重用代码吗?或者这会导致性能问题?使用内联表值函数封装SQL代码的性能

我研究联表值函数,这使我这个讨论: When would you use a table-valued function?

讨论的回答指出值函数“内嵌表允许优化治疗这些功能没有区别对象他们封装给你最佳的性能(假设你的索引和统计数据是理想的)。“

我最初的问题是,我试图将不同的数据源重新格式化为标准格式,然后将它们合并。我测试了联合6个不同的ITVF,而不是在一个查询中执行联合和转换。执行计划是相同的。由于我的背景是在oop中,我宁愿将查询拆分成更小的函数,但在我承诺在将来的项目中这样做时,我想知道是否使用过多的ITVF最终会导致性能问题。

+0

只是不要陷入这样一种常见的误解,即添加“RETURNS TABLE”使您的函数内联。它必须只是一个单一的陈述。如果你有变量或者多行代码,那么性能将会非常糟糕......甚至比标量函数还要糟糕。 –

+0

@SeanLange什么算作一个单一的陈述?是工会,交叉适用和子查询是否考虑过一个或多个陈述? –

+0

这将是一个单一的陈述。如果你必须把开始/结束块,你没有内联函数。如果你的函数定义是“... AS RETURN ...”,你的状态良好。 :) –

回答

0

可以使用内联表值函数(ITVF)来封装和重用代码吗?

是的。它们在多语句TVF中的优越性在于,由于使用多语句TVF,封装可以防止查询优化器将谓词推入TVF逻辑,并阻止它精确估计返回的行数。

或者这会导致性能问题?

简短的回答,通常不会。

较长的答案:

有4种方式来封装和重用查询逻辑(整个查询,而不只是标量表达式)。

  1. 查看
  2. 内嵌表值函数
  3. 多语句表值函数
  4. 临时表
  5. 表变量

视图和内联TVFs本来不降低性能,但它们增加了查询优化的复杂性。

凡优化不能始终如一地找到你可能需要干预的低成本计划。一种常见的方法是强制后台处理(即实现)中间结果,例如用多语句TVF替换Inline TVF,或者通过将结果提前后台打包到临时表中。在较大查询的上下文中运行时

假脱机在封装的查询的可能的优化的成本降低了包封的查询的复杂性。

当后台的结果,临时表通常是最好的,因为SQL服务器也可以有索引和统计,使SQL Server来准确地评估,这将消耗中间结果的计划的成本。

0

ITVF非常适合封装查询逻辑以便重复使用。我有十几份财务报告,所有这些财务报表都查询了大致相同的信息,并通过创建一个函数来提供这些数据,我可以肯定的是,我的所有报表都是从相同的数据体相同的过滤器和转换等等。

也就是说,您也可以轻松创建一个视图而不是ITVF,但ITVF还提供了一种基于发送的参数过滤或以其他方式转换数据的方法。例如,我的财务职能可以接受区名作为可选的输入参数,并且只返回该区的数据。通过这种方式使用ITVF,优化器可以随着时间的推移基于发送的参数优化查询计划,这有助于而不是阻碍性能。

我建议您不要在六个不同的ITVF上使用联合,而只需将所有表一起拖放到一个ITVF中:如果您的表模式或报表需求发生更改,那么只有一个地方可以进行更新。