有人能帮助我理解SQL Server中缓存函数的执行计划吗?
有没有相关在线资源可以参考?
有人能帮助我理解SQL Server中缓存函数的执行计划吗?
有没有相关在线资源可以参考?
被接受的答案存在不准确/误导性,主要是由于引用语句对于术语“用户定义函数”过于模糊。
在Microsoft SQL Server中有几种不同类型的用户定义函数,它们被处理方式不同:
多语句表值函数(Multi-statement TVFs):
这些函数被视为存储过程。执行它们的查询仅显示对它们名称的引用,而不是任何定义。它们在sys.dm_exec_cached_plans
中显示为“Compiled Plan”对象类型和“Proc”缓存对象类型。任何输入参数值也与计划一起存储,因此多语句表值函数存在参数卡顿问题。
内联表值函数(Inline TVFs或iTVFs):
这些函数被视为视图。执行它们的查询包含了它们的定义。它们在sys.dm_exec_cached_plans
中显示为“Parse Tree”对象类型和“View”缓存对象类型。输入参数值不与计划一起存储,因此内联表值函数不存在参数卡顿问题。
标量UDFs(Scalar UDFs):
这些函数被视为存储过程。执行它们的查询仅显示对它们名称的引用,而不是任何定义。它们在sys.dm_exec_cached_plans
中显示为“Compiled Plan”对象类型和“Proc”缓存对象类型。任何输入参数值也与计划一起存储,因此标量UDFs存在参数卡顿问题。此外,与上述两种表值函数不同但类似于常规存储过程,您可以使用EXEC[UTE]
而不是SELECT
或SET
通过WITH RECOMPILE
选项强制重新编译执行计划。
SQLCLR对象:
这些对象更像是客户端/应用程序代码。执行它们的查询只显示对它们名称的引用,而不包括它们的定义。它们在sys.dm_exec_cached_plans
中以“CLR编译函数”或“CLR编译存储过程”的cacheobjtype
和“存储过程”的objtype
出现。但是,与多语句表值函数和标量用户定义函数不同的是,它们没有定义,因此也没有相关联的查询计划。然而,它们执行的任何临时查询(非存储过程调用)都会显示在sys.dm_exec_cached_plans
中,其cacheobjtype
为“Compiled Plan”,objtype
为“Prepared”。如果任何这些临时查询有参数化,那么应该将初始输入参数值与预备计划一起存储,并因此受到参数嗅探问题的影响。
有关对象缓存的更多详细信息,请参阅Caching Mechanisms MSDN页面。
是的,它们确实会进入执行计划缓存。
sys.dm_exec_query_plan DMV将显示给定计划句柄的计划。引用自该处:
各种类型的Transact-SQL批处理(如临时批处理、存储过程和用户定义的函数)的查询计划被缓存在称为计划缓存的内存区域中。每个缓存的查询计划由唯一标识符(称为计划句柄)标识。您可以使用sys.dm_exec_query_plan动态管理视图指定此计划句柄,以检索特定Transact-SQL查询或批处理的执行计划。
SELECT
语句中创建索引。将其视为子查询或派生表。对于公共表表达式(CTE)也是如此,因为它们本质上是内联视图。同样,您可以在视图上创建索引,但不能在视图内部创建索引。 - Solomon Rutzky