sql在运行查询时以及在存储过程中运行该查询时使用不同的执行计划?
问题描述:
我有这个疑问,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 ..
,但我有这个procedure
sp_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个步骤是什么?这是什么?
答
SQL有很多原因可以使用不同的执行计划。这可能是:
- 对于相同的查询(您使用常量在你的第一个例子中,在第二查询可能有不同的值)
- 不同的数据(这意味着你在开发&运行的查询参数不同生产)
- 参数嗅探 - 更多下面,但首先通过过程可能有'所需'参数
- 不同的数据类型 - 正如@MartinSmith指出的,我们看不到参数声明。你可能有一个变量与它匹配的字段的类型不匹配。
参数嗅探
存储过程做“parameter sniffing”,这是一种幸福(如果你的作品)和诅咒(如果它的工作对你)。首先通过Zebr%
为zerbrowski搜索某人。姓氏索引实现这个非常具体,并且会返回,比方说,从百万行中的3行 - 所以一个执行计划就建立了。对于低排结果编译的proc,下一个搜索是S%
。那么,S是你最常用的名字,并且匹配100万中的93,543行。
那么你能做什么?
有很多,你可以花时间考察这个步骤....在可变数据类型仔细
- 看,比较广告典当查询时,PROC和基础表(SP_COLUMNS MYTABLE )。
- 隔离运动部件
- 确保您在两个查询使用相同的数据运行在同一系统中
- 在运行,使PROC的肯定首先运行跟踪使用预期的参数
- 尝试使用几个不同的参数运行您的广告附加查询,并查看执行计划如何更改。
- 如果您无法隔离活动,请临时将
WITH RECOMPILE
添加到proc以比较执行计划。或者,在运行之前执行DBCC FREEPROCCACHE
。 (免责声明 - 如果这是一个实时系统,请确保你了解这些将会做什么)。
可能是一种隐含的转换。第二个计划中的计算标量是什么? (在这个属性窗口中查看)。存储过程参数是否与第一个查询中的变量具有相同的数据类型? –
我认为@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