Sql 为什么在存储过程中使用if-else语句时执行查询需要更多时间?

Sql 为什么在存储过程中使用if-else语句时执行查询需要更多时间?,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我在存储过程中使用了以下查询。当我在存储过程中使用if-else语句时,执行查询需要更多的时间。当我删除if-else语句时,查询返回结果所用的时间更少 If @P_Make = 'ALL' Or IsNull(@P_Make, '') = '' Begin Set @P_Make = '%'; End Else Begin Set @P_Make = @P_Make + '%'; End If @P_Model = 'ALL' Or IsNull(@P_Model, '')

我在存储过程中使用了以下查询。当我在存储过程中使用if-else语句时,执行查询需要更多的时间。当我删除if-else语句时,查询返回结果所用的时间更少

If @P_Make = 'ALL' Or IsNull(@P_Make, '') = ''
Begin
    Set @P_Make = '%';
End
Else
Begin
    Set @P_Make = @P_Make + '%';
End 
If @P_Model = 'ALL' Or IsNull(@P_Model, '') = ''
Begin
    Set @P_Model = '%';
End
Else
Begin
    Set @P_Model = @P_Model + '%';
End     
If @P_Location = 'ALL' Or IsNull(@P_Location, '') = ''
Begin
    Set @P_Location = '%';
End
Else
Begin
    Set @P_Location = @P_Location + '%';
End
If @P_City = 'ALL' Or IsNull(@P_City, '') = ''
Begin
    Set @P_City = '%';
End
Else
Begin
    Set @P_City = @P_City + '%';
End
If @P_Category = 'ALL' Or IsNull(@P_Category, '') = ''
Begin
    Set @P_Category = '%';
End
Else
Begin
   Set @P_Category = Case When @P_Category = 'Bikes & Scooters' Then '2W%'
                             When @P_Category = '3 Wheelers' Then '3W%'
                             When @P_Category = 'Cars & SUVs' Then '4W%'
                             When @P_Category = 'Trucks' Then 'CV%'
                             When @P_Category = 'Farm Equipments' Then 'FE%'
                             When @P_Category = 'Industrial Equipments' Then 'IE%'
                             When @P_Category = 'Construction Equipments' Then 'CE%'
                             Else @P_Category + '%'
                        End
    End
If @P_Service = 'ALL' Or IsNull(@P_Service, '') = ''
Begin
    Set @P_Service = ''
End

Select Count(C.Sal_Pk_Id) 
From dbo.Auction (NoLock) A
Inner Join dbo.PLACE (NoLock) B On A.Auc_Place_Fk_Id = B.Place_Pk_Id
Inner Join dbo.SALES_DETAILS (NoLock) C On A.Auc_Code = C.Sal_Auc_Code
Inner Join dbo.AUCTIONSERVICES (NoLock) D On C.Sal_Regno = D.Auc_Service_Regno And C.Sal_Auc_Code = D.Auc_Service_Auctioncode
Inner Join dbo.LOT (NoLock) E On C.Sal_Lot_No = E.Lot_Lot_No And C.Sal_Auc_Code = E.Lot_Auc_Code 
Inner Join dbo.INVENTORY (NoLock) F On C.Sal_Regno = F.Inv_H_Reg_No
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And IsNull(B.Place_City, '') Like @P_City And IsNull(B.Place_State, '') Like @P_Location
And IsNull(F.Inv_H_Category, '') Like @P_Category And IsNull(F.Inv_H_Mfg_Name, '') Like @P_Make
And IsNull(F.Inv_H_Model, '') Like @P_Model
不带if-else语句的查询:

Select Count(C.Sal_Pk_Id) 
From dbo.Auction (NoLock) A
Inner Join dbo.PLACE (NoLock) B On A.Auc_Place_Fk_Id = B.Place_Pk_Id
Inner Join dbo.SALES_DETAILS (NoLock) C On A.Auc_Code = C.Sal_Auc_Code
Inner Join dbo.AUCTIONSERVICES (NoLock) D On C.Sal_Regno = D.Auc_Service_Regno And C.Sal_Auc_Code = D.Auc_Service_Auctioncode
Inner Join dbo.LOT (NoLock) E On C.Sal_Lot_No = E.Lot_Lot_No And C.Sal_Auc_Code = E.Lot_Auc_Code 
Inner Join dbo.INVENTORY (NoLock) F On C.Sal_Regno = F.Inv_H_Reg_No
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And (@P_City = '' Or IsNull(B.Place_City, '') = @P_City)
And (@P_Location= '' Or IsNull(B.Place_State, '') = @P_Location)
And (@P_Category = '' Or IsNull(F.Inv_H_Category, '') = @P_Category)
And (@P_Make = '' Or IsNull(F.Inv_H_Mfg_Name, '') = @P_Make)
And (@P_Model = '' Or IsNull(F.Inv_H_Model, '') = @P_Model)

为什么在删除存储过程中的if-else语句时查询输出花费的时间更少?

我认为没有if-else的查询速度更快,因为它没有Like运算符

Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And IsNull(B.Place_City, '') Like @P_City And IsNull(B.Place_State, '') Like @P_Location
And IsNull(F.Inv_H_Category, '') Like @P_Category And IsNull(F.Inv_H_Mfg_Name, '') Like @P_Make
And IsNull(F.Inv_H_Model, '') Like @P_Model

我认为第二个查询可以更有效地使用索引。第一个查询和第二个查询是不同的,请查看实际的执行计划,您将了解它发生的原因。

我认为没有if-else的查询更快,因为它没有Like运算符

Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And IsNull(B.Place_City, '') Like @P_City And IsNull(B.Place_State, '') Like @P_Location
And IsNull(F.Inv_H_Category, '') Like @P_Category And IsNull(F.Inv_H_Mfg_Name, '') Like @P_Make
And IsNull(F.Inv_H_Model, '') Like @P_Model

我认为第二个查询可以更有效地使用索引。第一个查询和第二个查询是不同的,请查看实际的执行计划,您将了解它发生的原因。

有两个主要原因-
和执行计划

比如“%something”
是您可以使用的最慢的筛选方法-它意味着逐行进行筛选,读取列中的全部数据并进行比较。它不能使用任何索引搜索,只能扫描

其次,根据调用过程的第一种方式,您只能得到一个执行计划。这几乎保证了对于任何其他输入数据,性能都会受到影响。在您的第二个示例中,虽然计划仍然是次优的,并且依赖于初始输入,但它并没有完全忽略所有可能的过滤器——它只是根据统计数据进行优化


动态过滤器不是以前没有人尝试解决的问题。向最好的人学习:

有两个主要原因-
和执行计划

比如“%something”
是您可以使用的最慢的筛选方法-它意味着逐行进行筛选,读取列中的全部数据并进行比较。它不能使用任何索引搜索,只能扫描

其次,根据调用过程的第一种方式,您只能得到一个执行计划。这几乎保证了对于任何其他输入数据,性能都会受到影响。在您的第二个示例中,虽然计划仍然是次优的,并且依赖于初始输入,但它并没有完全忽略所有可能的过滤器——它只是根据统计数据进行优化


动态过滤器不是以前没有人尝试解决的问题。向最好的人学习:

你在第一个查询中使用dbo.Auction table,在第二个查询中使用dbo.PASS\u Auction为什么?@NeerajPrasadSharma,我更新了我的问题。你在第一个查询中使用dbo.Auction table,在第二个查询中使用dbo.PASS\u Auction为什么?@NeerajPrasadSharma,我更新了我的问题。