【问题标题】:How can a stored proc have multiple execution plans?存储过程如何有多个执行计划?
【发布时间】:2015-09-01 12:18:04
【问题描述】:

我正在使用 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 行。我期待 1 行。

这个存储过程已经被修改了多次,所以我相信 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 参数的 if 条件只有 2 个。

if @a_flag = 0
begin
   ...
end 

if @a_flag = 1
begin
   ...
end

【问题讨论】:

标签: sql sql-server sql-execution-plan


【解决方案1】:

通常,SQL Server 将根据传入的参数值生成一个新的查询计划(这可以确定它将使用哪些索引,如果有的话)以及是否添加、更改或更新索引(在表/ proc 中使用的视图),因此 SQL Server 可能会决定使用一个或多个它以前忽略的索引更有效。 proc 中涉及的 SQL 越多,它也会在 SQL Server 端启动更多工作,因为它会尝试优化查询。如果数据发生变化(突然你在 NJ 有更多的客户,并且有一个查询和状态索引),它可能会决定使用该索引并且查询计划会改变。如果查询更改(架构更改)中涉及的任何表或视图也会使现有计划无效并导致生成新计划。

【讨论】:

    【解决方案2】:

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

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

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


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

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

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

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

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

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

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

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

    【讨论】:

    • 刚刚更新了问题以包含 proc 对参数和条件的定义。 proc 没有动态 SQL。这个过程总是从另一个过程中执行的。
    • 基于参数范围和 SP 中的 if/then 逻辑,SP 存在多个计划是有意义的。我可以询问为什么它很重要吗?该引擎旨在帮助规划最佳执行,当您的存储过程显然有多个路径时,关注多个执行计划的原因是什么?
    • 另外看看technet.microsoft.com/en-us/library/ee343986(v=sql.100).aspx它有很多关于执行计划的好信息,虽然它很长而且在某些地方很漂亮。
    • 感谢和很棒的解释。如果一个过程有多个执行计划,这真的没关系。这个问题对我来说更重要,因为我认为每个存储过程总是有 1 个执行计划。
    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2020-10-16
    • 2022-10-05
    • 2010-10-05
    相关资源
    最近更新 更多