2012-10-09 29 views
0

我有这个疑问,sql在运行查询时以及在存储过程中运行该查询时使用不同的执行计划?

Declare @Prcocessrate float 
declare @item varchar(20) 
declare @process varchar(20) 
declare @branch varchar(20) 
set @item = 'shirt' 
set @process = 'kt' 
set @branch = '1' 
select @Prcocessrate = ProcessPrice from itemwiseprocessrate where [email protected] and [email protected] and [email protected] 

当我运行它单手,执行计划只显示3个步骤,请参阅youself ..

enter image description here

,但我有这个proceduresp_newBooking as

ALTER PROC sp_newbooking 
-- other arguements-- 
AS 
BEGIN 

--OTHER FLAGS-- 

ELSE IF (@Flag = 32) 
     BEGIN 

      declare @ItemId varchar(max),@ProcessRate float 
      --set @BranchId='1' 
      select @ProcessCode = DefaultProcessCode from mstconfigsettings where [email protected] 
      select @ItemId= DefaultItemId from mstconfigsettings where [email protected] 
      select @ItemName= ItemName from itemmaster where [email protected] and [email protected] 
      select @ProcessRate = ProcessPrice from itemwiseprocessrate where [email protected] and [email protected] and [email protected] 
      if(@ProcessRate is not null) 
      select @ItemName as ItemName,@ProcessCode as ProcessCode,@ProcessRate as ProcessRate 
      else 
      select @ItemName as ItemName,@ProcessCode as ProcessCode,'0' as ProcessRate 
     END 

-- OTHER FLAGS -- 


END 

否当我运行这个

exec sp_newbooking 
@flag = 32, 
@Branchid = 1 

执行计划显示6个步骤!这里是图片..!
参见查询4

为何需要6个步骤,以执行相同的查询从过程执行时,而它的单独执行时采取3个步骤是什么?这是什么?

+2

可能是一种隐含的转换。第二个计划中的计算标量是什么? (在这个属性窗口中查看)。存储过程参数是否与第一个查询中的变量具有相同的数据类型? –

+0

我认为@MartinSmith是正确的。当您在proc外部运行查询时,您正在使用值为'1'的@ branch参数的varchar(20)类型。当你调用proc时,你指定@branchid = 1。在那里看到1没有引号。在调用sp时,SQL Server将值1(它是一个int)转换为一个varchar。我怀疑,如果你将你的SP称为'EXEC sp_newbooking @ flag = 32,@ branchID ='1'',你会得到相同的执行计划。 – Tobsey

回答

1

SQL有很多原因可以使用不同的执行计划。这可能是:

  • 对于相同的查询(您使用常量在你的第一个例子中,在第二查询可能有不同的值)
  • 不同的数据(这意味着你在开发&运行的查询参数不同生产)
  • 参数嗅探 - 更多下面,但首先通过过程可能有'所需'参数
  • 不同的数据类型 - 正如@MartinSmith指出的,我们看不到参数声明。你可能有一个变量与它匹配的字段的类型不匹配。

参数嗅探
存储过程做“parameter sniffing”,这是一种幸福(如果你的作品)和诅咒(如果它的工作对你)。首先通过Zebr%为zerbrowski搜索某人。姓氏索引实现这个非常具体,并且会返回,比方说,从百万行中的3行 - 所以一个执行计划就建立了。对于低排结果编译的proc,下一个搜索是S%。那么,S是你最常用的名字,并且匹配100万中的93,543行。

那么你能做什么?
有很多,你可以花时间考察这个步骤....在可变数据类型仔细

  • 看,比较广告典当查询时,PROC和基础表(SP_COLUMNS MYTABLE )。
  • 隔离运动部件
    • 确保您在两个查询使用相同的数据运行在同一系统中
    • 在运行,使PROC的肯定首先运行跟踪使用预期的参数
    • 尝试使用几个不同的参数运行您的广告附加查询,并查看执行计划如何更改。
    • 如果您无法隔离活动,请临时将WITH RECOMPILE添加到proc以比较执行计划。或者,在运行之前执行DBCC FREEPROCCACHE。 (免责声明 - 如果这是一个实时系统,请确保你了解这些将会做什么)。
相关问题