SQL Server 中是不是缓存了函数的执行计划?
Posted
技术标签:
【中文标题】SQL Server 中是不是缓存了函数的执行计划?【英文标题】:Are execution plan for functions cached in SQL server?SQL Server 中是否缓存了函数的执行计划? 【发布时间】:2011-03-06 16:09:03 【问题描述】:任何人都可以帮助我了解 SQL Server 中缓存的函数的执行计划吗?
有这方面的在线资源吗?
【问题讨论】:
【参考方案1】:是的,它们被考虑用于缓存。
http://msdn.microsoft.com/en-us/library/ms181055.aspx
【讨论】:
谢谢,但是在链接中没有写到用户定义的函数也被考虑用于计划缓存? 这是摘自文章的引述:When any SQL statement is executed in SQL Server, the relational engine first looks through the procedure cache to verify that an existing execution plan for the same SQL statement exists. SQL Server reuses any existing plan it finds, saving the overhead of recompiling the SQL statement. If no existing execution plan exists, SQL Server generates a new execution plan for the query.
【参考方案2】:
是的,它们确实进入了执行计划缓存。
sys.dm_exec_query_plan DMV 将显示给定计划句柄的计划。从那里引用:
各种类型的查询计划 Transact-SQL 批处理,例如 ad hoc 批处理、存储过程和 用户定义的函数,缓存在 称为计划的内存区域 缓存。每个缓存的查询计划是 由唯一标识符标识 称为计划句柄。您可以指定 该计划与 sys.dm_exec_query_plan 动态 管理视图以检索 特定的执行计划 Transact-SQL 查询或批处理。
【讨论】:
【参考方案3】:接受的答案不准确/具有误导性,主要是因为引用的引用对术语“用户定义的函数”过于含糊。
Microsoft SQL Server 中有几种不同类型的用户定义函数,它们的处理方式不同:
多语句 TVF:
这些被视为存储过程。执行它们的查询只显示对它们名称的引用,而不是对它们的任何定义的引用。它们出现在sys.dm_exec_cached_plans
中,带有“Compiled Plan”的cacheobjtype
和“Proc”的objtype
。任何输入参数值也与计划一起存储,因此多语句 TVF 会受到参数嗅探问题的影响。
内联 TVF (iTVF):
这些被视为视图。执行它们的查询包含它们的定义。它们出现在sys.dm_exec_cached_plans
中,带有“解析树”的cacheobjtype
和“视图”的objtype
。输入参数值不与计划一起存储,因此内联 TVF 不受到参数嗅探问题的影响。
标量 UDF:
这些被视为存储过程。执行它们的查询只显示对它们名称的引用,而不是对它们的任何定义的引用。它们出现在sys.dm_exec_cached_plans
中,带有“Compiled Plan”的cacheobjtype
和“Proc”的objtype
。任何输入参数值也与计划一起存储,因此标量 UDF 会受到参数嗅探问题的影响。此外,与上述两种类型的 TVF 不同,但与常规存储过程一样,您可以在通过 EXEC[UTE]
而不是 SELECT
或 SET
执行时使用 WITH RECOMPILE
选项强制重新编译执行计划。
SQLCLR 对象:
这些更像是客户端/应用程序代码。执行它们的查询只显示对它们名称的引用,而不是对它们的任何定义的引用。它们出现在sys.dm_exec_cached_plans
中,带有“CLR Compiled Func”或“CLR Compiled Proc”的cacheobjtype
,以及“Proc”的objtype
。但是,与多语句 TVF 和标量 UDF 不同,它们没有定义,因此没有关联的查询计划。但是,它们执行的任何即席查询(不是存储过程调用)都显示在 sys.dm_exec_cached_plans
中,带有“已编译计划”的 cacheobjtype
和“已准备”的 objtype
。任何这些即席查询(如果已参数化)都应将初始输入参数值与准备好的计划一起存储,因此会受到参数嗅探问题的影响。
有关对象缓存的更多详细信息,请参阅 Caching Mechanisms 上的 MSDN 页面。
【讨论】:
非常感谢您对每个案例的解释。您知道是否可以在 iTVF 上创建索引,因为它们被视为视图? @GabrielEspinoza 不,您不能在 iTVF 上创建索引,因为它们是未定义返回表模式的 内联 代码,并且您不能在SELECT
中创建索引陈述。将它们视为子查询或派生表。 CTE 也是如此,因为它们本质上是内联视图。同样,您可以在 视图上创建索引,但不能在 在 视图内创建索引。以上是关于SQL Server 中是不是缓存了函数的执行计划?的主要内容,如果未能解决你的问题,请参考以下文章