优化器如何执行标量函数

joe*_*c12 1 sql-server optimization functions

我在网上读到,标量函数会影响性能,因为优化器无法访问标量函数的内容。由于该函数是针对每一行执行的,因此优化器是否必须每次都为函数的内容构建执行计划,或者是否在第一次访问该函数时构建该计划,然后将其用于所有其他行?

Cha*_*ace 5

对于未内联的标量 UDF ,实际的查询计划仅生成一次(显然假设在执行之间没有统计信息更新、索引重建或任何 DDL 更改)。该计划像任何其他查询计划一样被缓存和重用。

它不会在 中获取任何数据sys.dm_exec_query_stats,因此您无法通过这种方式获得任何统计信息。但您可以用来sys.dm_exec_function_stats获取类似的信息。

您可以使用以下查询查看缓存的查询计划

SELECT
  p.objtype,
  OBJECT_NAME(f.object_id),
  st.text,
  qp.query_plan,
  p.refcounts,
  p.usecounts,
  f.execution_count
FROM sys.dm_exec_function_stats f
JOIN sys.dm_exec_cached_plans p ON p.plan_handle = f.plan_handle
CROSS APPLY sys.dm_exec_query_plan(p.plan_handle) qp
CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) st
WHERE f.object_id = OBJECT_ID(N'dbo.fnTest')
OPTION(RECOMPILE);
Run Code Online (Sandbox Code Playgroud)

您可以使用数据库范围配置EXEC_QUERY_STATS_FOR_SCALAR_FUNCTIONS打开或关闭此功能(到目前为止,该旋钮仅适用于 Azure SQL DB 和托管实例)。


函数的实际执行确实发生在单独的作用域中,需要对参数进行编组并前后返回结果,以及上下文切换(SET例如不同的选项和不同的局部变量作用域)。这是他们表现如此糟糕的主要原因之一。