使用内联 table 值函数封装 SQL 代码的性能
Performance using Inline table valued function to encapsulate SQL code
问题是:内联table值函数(ITVF)是否可以用来封装和重用代码?或者这会导致性能问题吗?
我正在研究内联 table 值函数,这使我进行了以下讨论:
讨论中的一个答案指出内联 table 值函数 "allows the optimizer to treat these functions no differently than the objects they encapsulate giving you optimum performance (assuming that your indexes and statistics are ideal)."
我最初的问题是我试图将不同的数据源重新格式化为标准格式,然后合并它们。我测试了联合 6 个不同的 ITVF 与在一个查询中执行联合和转换的对比。执行计划是相同的。
由于我的背景是 oop,我更愿意将查询拆分成更小的函数,但在我承诺在未来的项目中这样做之前,我想知道使用太多 ITVF 是否最终会导致性能问题。
ITVF 非常适合封装查询逻辑以供重用。我有十几个财务报告,它们都查询同一组 table 以获得大致相同的信息,并且通过创建一个函数来提供该数据,我可以确定我的所有报告都来自同一个具有相同过滤器和转换等的数据主体
也就是说,您也可以轻松地创建一个视图而不是 ITVF,但是 ITVF 还提供了一种根据发送的参数过滤或以其他方式转换数据的方法。例如,我的财务功能可以接受作为可选输入参数的地区名称和该地区的唯一 return 数据。通过以这种方式使用 ITVF,随着时间的推移,优化器可以根据发送的参数优化查询计划,这有助于而不是阻碍性能。
我建议不要在六个不同的 ITVF 上联合,只需将所有 table 拉到一个单一的 ITVF 中:这样,如果您的 table 模式或报告需求发生变化。
Can inline table valued functions (ITVF) be used to encapsulate and reuse code?
是的。它们在这方面优于多语句 TVF,因为对于多语句 TVF,封装可防止查询优化器将谓词推入 TVF 逻辑,并防止它准确估计返回的行数。
Or will this result in performance issues?
简短回答,通常不会。
更长的答案:
有 4 种方法来封装和重用查询逻辑(整个查询,而不仅仅是标量表达式)。
- 观看次数
- 内联Table值函数
- 多语句Table 值函数
- 临时Tables
- Table 变量
视图和内联 TVF 本质上不会降低性能,但它们会增加查询优化的复杂性。
如果优化器无法始终如一地找到低成本计划,您可能需要进行干预。一种常见的方法是强制假脱机(即具体化)中间结果,例如用多语句 TVF 替换内联 TVF,或者提前将结果假脱机到 temp table。
当 运行 在较大查询的上下文中时,假脱机以可能优化封装查询为代价降低了封装查询的复杂性。
当假脱机结果时,Temp Tables 通常是最好的,因为 SQL Server 它们可以有索引和统计信息,使 SQL Server 能够准确评估计划的成本这将消耗中间结果。
问题是:内联table值函数(ITVF)是否可以用来封装和重用代码?或者这会导致性能问题吗?
我正在研究内联 table 值函数,这使我进行了以下讨论:
讨论中的一个答案指出内联 table 值函数 "allows the optimizer to treat these functions no differently than the objects they encapsulate giving you optimum performance (assuming that your indexes and statistics are ideal)."
我最初的问题是我试图将不同的数据源重新格式化为标准格式,然后合并它们。我测试了联合 6 个不同的 ITVF 与在一个查询中执行联合和转换的对比。执行计划是相同的。
由于我的背景是 oop,我更愿意将查询拆分成更小的函数,但在我承诺在未来的项目中这样做之前,我想知道使用太多 ITVF 是否最终会导致性能问题。
ITVF 非常适合封装查询逻辑以供重用。我有十几个财务报告,它们都查询同一组 table 以获得大致相同的信息,并且通过创建一个函数来提供该数据,我可以确定我的所有报告都来自同一个具有相同过滤器和转换等的数据主体
也就是说,您也可以轻松地创建一个视图而不是 ITVF,但是 ITVF 还提供了一种根据发送的参数过滤或以其他方式转换数据的方法。例如,我的财务功能可以接受作为可选输入参数的地区名称和该地区的唯一 return 数据。通过以这种方式使用 ITVF,随着时间的推移,优化器可以根据发送的参数优化查询计划,这有助于而不是阻碍性能。
我建议不要在六个不同的 ITVF 上联合,只需将所有 table 拉到一个单一的 ITVF 中:这样,如果您的 table 模式或报告需求发生变化。
Can inline table valued functions (ITVF) be used to encapsulate and reuse code?
是的。它们在这方面优于多语句 TVF,因为对于多语句 TVF,封装可防止查询优化器将谓词推入 TVF 逻辑,并防止它准确估计返回的行数。
Or will this result in performance issues?
简短回答,通常不会。
更长的答案:
有 4 种方法来封装和重用查询逻辑(整个查询,而不仅仅是标量表达式)。
- 观看次数
- 内联Table值函数
- 多语句Table 值函数
- 临时Tables
- Table 变量
视图和内联 TVF 本质上不会降低性能,但它们会增加查询优化的复杂性。
如果优化器无法始终如一地找到低成本计划,您可能需要进行干预。一种常见的方法是强制假脱机(即具体化)中间结果,例如用多语句 TVF 替换内联 TVF,或者提前将结果假脱机到 temp table。
当 运行 在较大查询的上下文中时,假脱机以可能优化封装查询为代价降低了封装查询的复杂性。
当假脱机结果时,Temp Tables 通常是最好的,因为 SQL Server 它们可以有索引和统计信息,使 SQL Server 能够准确评估计划的成本这将消耗中间结果。