SQL Server 如何将计划指南与查询匹配

SQL Server 将 OBJECT 类型的计划向导与在 sp_create_plan_guide 存储过程的 @module_or_batch 参数中命名的存储过程、触发器、或函数(模块)内出现的查询匹配。如果计划向导位于模块中,则该计划向导将与指定的查询匹配。

对于在批处理内提交的查询,SQL Server 通过首先尝试将查询与基于 SQL 的计划向导匹配,再尝试参数化查询,然后再次尝试匹配其他查询,直到将计划向导与这些查询匹配为止。下图简要介绍了这一过程。

SQL Server 如何将计划指南与查询相匹配

  1. SQL Server 查询优化器将执行的批处理识别为编译批处理内的每条语句的请求。

  2. 对于批处理内的特定语句,SQL Server 尝试将该语句与基于 SQL 的计划指南匹配,该指南的 @module_or_batch 参数与传入批处理文本的参数匹配(包含所有常量文字值);该指南的 @stmt 参数也与批处理中的语句匹配。如果存在此类计划指南并且匹配成功,则会修改语句文本,以包括计划指南中指定的查询提示。随后将相应地编译语句。

  3. 如果计划向导与步骤 2 中的语句不匹配,则 SQL Server 将尝试使用强制参数化来参数化该语句。在此步骤中,参数化可能由于下列任何一个原因而失败:

    1. 该语句已经被参数化,或者包含本地变量。

    2. 应用了 PARAMETERIZATION SIMPLE 数据库 SET 选项(默认设置),但没有将任何 TEMPLATE 类型的计划向导应用于该语句,并且没有任何 TEMPLATE 类型的计划向导指定 PARAMETERIZATION FORCED 查询提示。

    3. 已经有 TEMPLATE 类型的计划向导应用于该语句,并且指定 PARAMETERIZATION SIMPLE 查询提示。

    如果强制参数化成功,则 SQL Server 尝试将参数化格式的该语句与对该参数化语句创建的 SQL 类型的计划向导匹配。如果存在此类计划指南并且匹配成功,则会修改语句文本,以包括计划指南中指定的查询提示。随后将相应地编译语句。如果未与此类计划向导匹配,将编译该参数化语句,而无需事先由计划向导修改该语句。

  4. 如果步骤 3 中的参数化失败,SQL Server 将再次尝试参数化该语句。这一次,SQL Server 将应用默认的简单参数化行为。然后,直接编译结果查询。计划向导与简单参数化的结果不匹配。

    注意注意

    在应用于通过强制参数化或简单参数化进行参数化的查询的 SQL 类型的计划向导中,将忽略 RECOMPILE 查询提示。还会发出一条警告。