问题是:可以使用内联表值函数(ITVF)来封装和重用代码吗?或者这会导致性能问题吗?
我正在研究内联表值函数,这引出了我的讨论: When would you use a table-valued function?
讨论中的一个答案表明,内联表值函数“允许优化器处理这些函数与它们封装的对象没有什么不同,从而为您提供最佳性能(假设您的索引和统计数据是理想的)。”
我最初的问题是我试图将不同的数据源重新格式化为标准格式,然后将它们联合起来。我测试了联合6种不同的ITVF,而不是在一个查询中执行联合和转换。执行计划完全相同。
由于我的背景是oop,我宁愿将查询分成更小的函数,但在我承诺在未来的项目中执行此操作之前,我想知道使用太多的ITVF最终是否会导致性能问题。
答案 0 :(得分:1)
ITVF非常适合封装查询逻辑以供重用。我有十几个财务报告,它们都查询相同的表集以获得大致相同的信息,并且通过创建提供该数据的函数,我可以确保我的所有报告都是从同一个数据体中提取的。相同的过滤器和转换等。
话虽如此,您也可以轻松创建视图而不是ITVF,但ITVF还提供了一种根据发送的参数过滤或以其他方式转换数据的方法。例如,我的财务功能可以接受某个区域name作为可选输入参数,仅返回该区域的数据。通过这种方式使用ITVF,优化器可以根据发送的参数优化查询计划,这有助于而不是阻碍性能。
我建议在六个不同的ITVF上使用联合而不是联合,只需将所有表格合并到一个ITVF中:这样,如果表格模式或报表需求发生变化,您只有一个地方可以进行更新。
答案 1 :(得分:1)
可以使用内联表值函数(ITVF)来封装和重用代码吗?
是。它们在多语句TVF中更胜一筹,因为使用多语句TVF,封装可以防止查询优化器将谓词推入TVF逻辑,并阻止它准确估计返回的行数。
或者这会导致性能问题吗?
简短回答,通常不是。
更长的答案:
有四种方法可以封装和重用查询逻辑(整个查询,而不仅仅是标量表达式)。
视图和内联TVF本质上不会降低性能,但它们会增加查询优化的复杂性。
如果优化程序无法始终如一地找到低成本计划,您可能需要进行干预。一种常见的方法是强制中间结果的假脱机(即具体化),例如用多语句TVF替换内联TVF,或者将结果预先假设为临时表。
当在较大查询的上下文中运行时,假脱机降低了封装查询的复杂性,代价是可能优化封装查询。
在假脱机结果时,临时表通常是最好的,因为SQL Server可以使用索引和统计信息,使SQL Server能够准确评估将消耗中间结果的计划的成本。