问题是:内联表值函数(ITVF)能否用于封装和重用代码?或者这会导致性能问题吗?
我正在研究内联表值函数,这导致了下面的讨论:When would you use a table-valued function?
讨论中的一个回答是,内联表值函数“允许优化器对这些函数的处理与它们封装的对象没有什么不同(假设您的索引和统计数据是理想的)”。
我最初的问题是,我试图将不同的数据源重新格式化为标准格式,然后将它们合并。我在一个查询中测试了联合6种不同的ITVF,而不是执行联合和转换。执行计划是一样的。
由于我的背景是面向对象操作( oop ),所以我倾向于将查询分成更小的函数,但是在我承诺在整个未来的项目中这样做之前,我想知道使用太多的ITVF最终是否会导致性能问题。
发布于 2017-06-15 21:20:08
内联表值函数(ITVF)可以用于封装和重用代码吗?
是。在这方面,它们优于多语句TVFs,因为使用多语句TVF,封装防止查询优化器将谓词推入TVF逻辑,并阻止它准确估计返回的行数。
或者这会导致性能问题吗?
简短的回答,不是典型的。
较长的答覆:
有4种方法来封装和重用查询逻辑(整个查询,而不仅仅是标量表达式)。
视图和内联TVF本身并没有降低性能,但是它们增加了查询优化的复杂性。
如果优化器未能始终找到低成本的计划,则可能需要进行干预。一种常见的方法是强制中间结果的假脱机(即物化),例如用多语句TVF替换内联TVF,或者提前将结果假脱机到临时表。
假脱机降低了封装查询的复杂性,代价是在较大查询的上下文中运行时可能会优化封装的查询。
在后台处理结果时,临时表通常是最好的,因为Server可以有索引和统计信息,使Server能够准确地评估消耗中间结果的计划的成本。
发布于 2017-06-15 21:18:17
ITVFs对于封装可重用的查询逻辑来说是完美的.我有十几份财务报告,它们都在同一组表中查询大致相同的信息,通过创建一个函数来提供数据,我可以确保我的所有报告都是用相同的过滤器和转换从同一数据体中提取出来的,等等。
尽管如此,您也可以轻松地创建一个视图,而不是一个ITVF,但是ITVFs还提供了一种基于发送的参数过滤或转换数据的方法。例如,我的财务函数可以接受一个地区名称作为一个可选的输入参数,并且只返回该地区的数据。通过这种方式使用ITVFs,优化器可以根据输入的参数来优化查询计划,这有助于而不是阻碍性能。
我建议您不要在六个不同的ITVF上联合使用,只需将所有表合并到一个ITVF中即可:这样,如果表模式或报表需要更改,您只能在一个地方进行更新。
https://stackoverflow.com/questions/44576814
复制相似问题