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

时间:2015-06-16 15:16:38

标签: 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()

以上查询返回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

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

if @a_flag = 0
begin
   ...
end 

if @a_flag = 1
begin
   ...
end

2 个答案:

答案 0 :(得分:3)

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

  1. proc是否使用了大量if this then this select, else this select/update
  2. proc是否包含动态sql?
  3. 您是从网络还是SSMS执行SP?然后,您可能正在使用不同的连接设置执行SP。
  4. 存储过程是否有参数?有时,参数的差异可能导致一个执行计划对于特定集合来说很糟糕,因此使用了不同的计划。
  5. 尝试一个可能有帮助的类比......也许......

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

    1. 杂货店可以处理杂货,离你家最近(5分钟)。
    2. Target可以处理空气过滤器杂货,但增加25分钟的旅行时间。
    3. “一切都很重要”拥有您可能需要的一切,但距离一小时车程。
    4. 所以在这里,根据您的参数@needsAirFilter@needsBigPackOfSomething可能会极大地改变您的“购物”存储过程的“执行计划”。

      如果@needsAirFilter@needsBigPackOfSomethingfalse,则没有理由进行30分钟或小时的驾驶,因为您需要的一切都在杂货店。

      一个月,@needsAirFilter是真的,在这种情况下我们需要去Target,因为杂货店的执行计划不够。

      每年4次@needsBigPackOfSomething是正确的,我们需要花一小时的时间来获取大量的东西,同时抓住杂货,然后我们在那里进行空气过滤。

      当然......我们 可以 让小时驾驶 每个 时间来获取杂货,而另一个需要的东西(想象单一的执行计划)。但这绝不是 最有效的方法 。在这种情况下,我们对实际需要的信息/商品有不同的执行计划。

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

答案 1 :(得分:1)

通常,SQL Server将生成一个新的查询计划,具体取决于传入的参数的值(这可以确定它将使用哪些索引,如果有的话)以及是否添加,更改或更新索引(在表/上)在proc中使用的视图)因此SQL Server可能会决定使用它先前忽略的一个或多个索引更有效。在尝试优化查询时,proc中的SQL涉及的内容也将在SQL Server端启动更多工作。如果数据发生变化(突然你在新泽西州有更多的客户,并且有状态的查询和索引),它可能会决定它将使用该索引并更改查询计划。