【发布时间】:2011-03-06 16:09:03
【问题描述】:
任何人都可以帮助我了解 SQL Server 中缓存的函数的执行计划吗?
有这方面的在线资源吗?
【问题讨论】:
标签: sql-server function tsql sql-execution-plan sql-function
任何人都可以帮助我了解 SQL Server 中缓存的函数的执行计划吗?
有这方面的在线资源吗?
【问题讨论】:
标签: sql-server function tsql sql-execution-plan sql-function
是的,它们被考虑用于缓存。
【讨论】:
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.
是的,它们确实进入了执行计划缓存。
sys.dm_exec_query_plan DMV 将显示给定计划句柄的计划。从那里引用:
各种类型的查询计划 Transact-SQL 批处理,例如 ad hoc 批处理、存储过程和 用户定义的函数,缓存在 称为计划的内存区域 缓存。每个缓存的查询计划是 由唯一标识符标识 称为计划句柄。您可以指定 该计划与 sys.dm_exec_query_plan 动态 管理视图以检索 特定的执行计划 Transact-SQL 查询或批处理。
【讨论】:
接受的答案不准确/具有误导性,主要是因为引用的引用对术语“用户定义的函数”过于含糊。
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 页面。
【讨论】:
SELECT 中创建索引陈述。将它们视为子查询或派生表。 CTE 也是如此,因为它们本质上是内联视图。同样,您可以在 视图上创建索引,但不能在 在 视图内创建索引。