服务器配置:针对即席工作负荷进行优化

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例分析平台系统 (PDW)

此选项 optimize for ad hoc workloads 用于提高包含多个单用即席批处理的工作负荷的计划缓存的效率。 如果该选项设置为 1,则数据库引擎将在首次编译批处理时在计划缓存中存储一个编译的小计划存根,而不是存储完全编译的计划。 此选项可通过避免无法重用的编译计划占满计划缓存,来帮助缓解内存压力。 但是,启用此选项可能会影响对一次性计划进行故障排除的能力。

编译的计划存根允许数据库引擎识别此临时批次是在之前编译的,仅存储编译的计划存根。 当再次调用此批处理(重新编译或执行)时,数据库引擎会编译该批处理,从计划缓存中删除编译计划存根,并将完整编译计划添加到计划缓存中。

可以通过查询 sys.dm_exec_cached_plans 目录视图,并在 cacheobjtype 列中查找“Compiled Plan”来找到编译计划存根。 存根具有唯一的 plan_handle 标识符。 编译计划存根没有与其关联的执行计划,并且查询计划句柄不会返回图形或 XML 显示计划。

跟踪标志 8032 将缓存限制参数还原到 SQL Server 2005 (9.x) RTM 设置,这通常允许缓存更大。 当频繁重复使用的缓存条目无法容纳在缓存中时,以及 optimize for ad hoc workloads 选项未能解决计划缓存问题时,请使用此设置。

警告

如果大型缓存使其他内存使用者(如缓冲池)可用的内存较少,跟踪标志 8032 可能会导致性能不佳。

注解

optimize for ad hoc workloads将选项设置为1仅影响新计划;计划缓存中已有的计划不受影响。

若要立即影响已缓存的查询计划,需要使用 CLEAR PROCEDURE_CACHE 清除ALTER DATABASE SCOPED CONFIGURATION计划缓存,或SQL Server必须重启。

建议

避免计划缓存中存在大量一次性计划。 常见原因包括:

  • 不统一定义查询参数的数据类型。 这尤其适用于字符串的长度,但可应用到具有最大长度、精度或规模的任何数据类型。 例如,如果名为 @Greeting 的参数在一次调用时传递为 nvarchar(10) 并在下次调用时传递为 nvarchar(20),则将为每个参数大小创建各自的计划。

  • 未参数化的查询。 如果查询具有一个或多个参数,其中硬编码的值将提交到数据库引擎,则每个查询可能存在大量的查询计划。 计划可能因所使用的查询参数数据类型和长度的每种组合而存在。

如果一次性计划的数量在 OLTP 服务器的 SQL Server 数据库引擎内存中占了很大一部分(并且这些计划是临时计划),请使用这个服务器选项降低这些对象的内存使用量。

optimize for ad hoc workloads如果启用此选项,则无法查看单用查询的执行计划,因为只缓存计划存根。 根据环境和工作负荷,可以从以下两项功能中受益:

  • SQL Server 2016 (13.x) 中推出的查询存储功能可帮助你快速查找因查询计划有变导致的性能差异。 默认情况下,在 SQL Server 2022(16.x)及更高版本中的新数据库上启用查询存储。

  • 强制参数化通过降低查询编译和重新编译的频率,可以提高某些数据库的性能。 通常能从强制参数化中受益的数据库,会处理来自销售点 (POS) 应用程序等来源的大量并发查询。

    由于参数敏感度,强制参数化可能会导致性能问题。 有关详细信息,请参阅调查并解决参数敏感问题。 SQL Server 2022(16.x)及更高版本还可以启用参数敏感计划优化

示例

要获取一次性缓存计划的数量,请运行下列查询:

SELECT objtype,
    cacheobjtype,
    SUM(refcounts) AS AllRefObjects,
    SUM(CAST(size_in_bytes AS BIGINT)) / 1024 / 1024 AS SizeInMB
FROM sys.dm_exec_cached_plans
WHERE objtype = 'Adhoc'
    AND usecounts = 1
GROUP BY objtype, cacheobjtype;