查询存储中强制计划的奇怪行为

ada*_*m.g 2 sql-server query-store

我在查询存储中强制执行计划。计划与每天运行一次的作业中的过程相关联。这项工作的步骤之一就是:

EXEC [schema].[LoadData]
Run Code Online (Sandbox Code Playgroud)

过程 [schema].[LoadData] 看起来像

TRUNCATE TABLE [schema].[Data];
     
    INSERT INTO [schema].[Data]
           ([A1],
           [A2],
          .
          .
          .,
          [A49]
    )                
    SELECT *
        ,CURRENT_TIMESTAMP AS [Insert TimeStamp] 
    FROM [schema].[View]   
Run Code Online (Sandbox Code Playgroud)

其中 view 是包含一些 CTE 并使用同义词的视图(连接到来自不同数据库的表)。

在查询存储中执行如下所示: 在此输入图像描述

为了测试强制计划是否有效,我按照以下步骤操作:

  1. 在 SSMS 中运行查询 ->EXEC [schema].[LoadData]
  2. 上面的执行被视为不同的查询,因此在查询存储中没有看到任何新的查询 = 7
  3. DBA 仅使用运行查询的步骤创建一个新作业 ->EXEC [schema].[LoadData]
  4. 运行上述新创建的作业导致计划 ID = 29800

问题为什么执行计划没有被强制?在“强制计划失败计数”列中为 0。

Pau*_*ite 7

有可能计划 ID 29800 确实是强制的,但查询存储使得这一点很难看到。

计划强制并不能保证新计划与原始计划相同sp_query_store_force_plan,如(已添加重点)中所述:

此功能强制生成的执行计划将与强制执行的计划相同或相似。由于生成的计划可能与 sp_query_store_force_plan 指定的计划不同,因此计划的性能可能会有所不同。

如果生成的计划不相同,您将看到一个新的计划 ID。这并不一定意味着计划强制失败。query_store_plan_forcing_failed当计划强制失败时,将触发扩展事件。

UsePlan="1"您可以通过查看元素中属性的 id 为 29800 的计划 xml 来验证计划强制是否成功QueryPlan。它还显示为图形计划根部的属性。计划 ID 29800 也将出现在“带有强制计划的查询”报告中。

您可能想阅读 Erland Sommarskog 在他的文章《应用程序缓慢,SSMS 快速?》中的解释。

Kendra Little 在《什么是“道德等效执行计划”》和《为什么它好?》中也很好地讨论了这个问题。

顺便说一句,SSMS 生成不同查询 ID 的原因几乎可以肯定是因为您的作业步骤中没有SET QUOTED_IDENTIFIER ON,或者您已将 SSMS 配置为SET ARITHABORT ON(这是毫无意义的默认值)。