0

我有这个疑问,

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 itemname=@Item and Process=@process and branchid=@branch

当我单手运行它时,执行计划只显示3 个步骤,你自己看看..

在此处输入图像描述

但我有procedure sp_newBooking这个

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 branchid=@BranchId
            select @ItemId= DefaultItemId from mstconfigsettings where branchid=@BranchId
            select @ItemName=  ItemName from itemmaster where itemid=@ItemId and branchid=@BranchId
            select @ProcessRate =  ProcessPrice from itemwiseprocessrate where itemname=@ItemName and ProcessCode=@ProcessCode and branchid=@BranchId
            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 个步骤?这是吗?

4

1 回答 1

1

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

  • 相同查询的不同参数(您在第一个示例中使用常量,第二个示例中的查询可能具有不同的值)
  • 不同的数据(意味着您正在开发和生产上运行查询)
  • 参数嗅探——更多下文,但首先传递过程可能具有“所需”参数
  • 不同的数据类型 - 正如@MartinSmith 指出的那样,我们看不到参数声明。您可能有一个与其匹配的字段类型不匹配的变量。

参数嗅探
存储过程执行“参数嗅探”,这是一种祝福(如果它对您有用),也是一种诅咒(如果它对您不利)。首先通过某人搜索Zebr%zerbrowski。姓氏索引意识到这是非常具体的,并且会从一百万中返回 3 行——因此构建了一个执行计划。为低行结果编译 proc 后,下一个搜索是S%. 嗯,S 是您最常用的名称,匹配 100 万行中的 93,543 行。

所以,你可以做什么?
你可以采取很多步骤来检查这个....

  • 仔细查看变量数据类型,比较您的即席查询、proc 和基础表 (sp_columns mytable )。
  • 隔离运动部件
    • 确保您在同一系统中使用相同数据运行两个查询
    • 运行跟踪以确保 proc 的第一次运行使用预期的参数
    • 尝试使用几个不同的参数运行临时查询,看看执行计划如何变化。
    • 如果您无法隔离活动,请暂时添加WITH RECOMPILE到 proc 以比较执行计划。或者,DBCC FREEPROCCACHE在跑步前做一个。(免责声明 - 如果这是一个实时系统,请确保您了解这些将做什么)。
于 2012-10-09T16:20:22.480 回答