存储过程如何具有多个执行计划?

srh*_*srh 5 sql sql-server sql-execution-plan

我正在使用MS SQL Server 2008 R2.我有一个名为rpt_getWeeklyScheduleData的存储过程.这是我用于在特定数据库中查找其执行计划的查询:

select 
   *
from 
   sys.dm_exec_cached_plans cp
      CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
where 
   OBJECT_NAME(st.objectid, st.dbid) = 'rpt_getWeeklyScheduleData' and 
   st.dbid = DB_ID()
Run Code Online (Sandbox Code Playgroud)

上面的查询返回9行.我期待一排.

此存储过程已被多次修改,因此我相信SQL Server在修改和运行时一直在为其构建新的执行计划.这是正确的解释吗?如果没有,那你怎么解释这个?

还有可能看到每个计划何时创建?如果是,那怎么样?

更新:

这是存储过程的签名:

CREATE procedure [dbo].[rpt_getWeeklyScheduleData]
(
   @a_paaipk        int,
   @a_location_code int,
   @a_department_code   int,
   @a_week_start_date   varchar(12),
   @a_week_end_date varchar(12),
   @a_language_code int,
   @a_flag      int 
)
as
begin
   ...
end
Run Code Online (Sandbox Code Playgroud)

存储过程很长; 如果条件都为@a_flag参数,则只有2个.

if @a_flag = 0
begin
   ...
end 

if @a_flag = 1
begin
   ...
end
Run Code Online (Sandbox Code Playgroud)

Kri*_*ner 4

根据存储过程的性质(未提供),这很可能出于多种原因(很可能不限于以下原因):

  1. proc 是否使用了很多if this then this select, else this select/update
  2. proc中是否包含动态sql?
  3. 您是否同时从 Web 和 SSMS 执行 SP?然后您可能会使用不同的连接设置来执行 SP。
  4. 存储过程有参数吗?有时,参数的差异可能会导致一个执行计划对于特定的集合来说很糟糕,因此会使用不同的计划。

尝试做一个可能有帮助的类比……也许……


假设您有一个用于周末购物的存储过程。您通常需要购买杂货,有时需要购买空气过滤器,甚至更少需要购买一大包每年需要更换 4 次的东西。

  1. 杂货店可以处理杂货,并且距离您家最近(5 分钟)。
  2. 目标可以处理空气过滤器杂货,但会增加 25 分钟的旅行时间。
  3. “应有尽有的大地方”拥有您可能需要的一切,但距离酒店只有一个小时的车程。

所以在这里,取决于你的参数@needsAirFilter@needsBigPackOfSomething可能会极大地改变您的“购物”存储过程的“执行计划”。

如果@needsAirFilter@needsBigPackOfSomethingfalse则没有理由开车 30 分钟或小时,因为杂货店里有您需要的一切。

一个月一次,@needsAirFilter,这样的话我们就需要去塔吉特,因为杂货店的执行计划不够。

一年4次@needsBigPackOfSomething是真的,而且我们需要花一个小时的车程去拿一大包东西,同时还要去买杂货和空气过滤器,因为我们在那里。

当然......我们可以每次开车一个小时去买杂货,并在需要时做其他事情(想象一下单一的执行计划)。但这绝不是最有效的方法。在这种情况下,我们对于实际需要的信息/商品有不同的执行计划。

不知道这是否有帮助......但我玩得很开心:D