我正在使用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
答案 0 :(得分:3)
根据存储过程的性质(未提供),这很可能由于多种原因(很可能不限于以下):
if this then this select, else this select/update
尝试一个可能有帮助的类比......也许......
假设您有周末购物的存储过程。 您通常需要购买杂货,有时需要空气过滤器,甚至更少需要每年更换4次的大包装。
所以在这里,根据您的参数@needsAirFilter
和@needsBigPackOfSomething
可能会极大地改变您的“购物”存储过程的“执行计划”。
如果@needsAirFilter
和@needsBigPackOfSomething
是false
,则没有理由进行30分钟或小时的驾驶,因为您需要的一切都在杂货店。
一个月,@needsAirFilter
是真的,在这种情况下我们需要去Target,因为杂货店的执行计划不够。
@needsBigPackOfSomething
是正确的,我们需要花一小时的时间来获取大量的东西,同时抓住杂货,然后我们在那里进行空气过滤。
当然......我们 可以 让小时驾驶 每个 时间来获取杂货,而另一个需要的东西(想象单一的执行计划)。但这绝不是 最有效的方法 。在这种情况下,我们对实际需要的信息/商品有不同的执行计划。
不知道这是否有帮助...但我玩得很开心:D
答案 1 :(得分:1)
通常,SQL Server将生成一个新的查询计划,具体取决于传入的参数的值(这可以确定它将使用哪些索引,如果有的话)以及是否添加,更改或更新索引(在表/上)在proc中使用的视图)因此SQL Server可能会决定使用它先前忽略的一个或多个索引更有效。在尝试优化查询时,proc中的SQL涉及的内容也将在SQL Server端启动更多工作。如果数据发生变化(突然你在新泽西州有更多的客户,并且有状态的查询和索引),它可能会决定它将使用该索引并更改查询计划。