查询执行时使用标量函数花费太多时间

时间:2016-09-07 09:49:49

标签: sql-server stored-procedures user-defined-functions

我有一个Scalar函数,它根据条件和函数计算总和,我使用的是存储过程。这花费了太多时间来执行。 25条记录大约需要4分钟。有什么想法我可以优化我的查询。任何帮助将不胜感激。

这是我的代码。 存储过程动态查询我调用函数。

select distinct
                        p.ProductID
                        ,p.ProductGUID
                        ,p.[ProductNumber] 
                        ,[ProductName] = isnull(p.[Name],'''')
                        ,[ProductNumberLabel] = isnull(p.[ProductNumberLabel],'''')
                        ,[ProductDescription]=isnull(p.[Description],'''')
                        ,[PrimaryImageID] = isnull(p.[PrimaryImageID],0)
                        ,[UserProductID] = isnull(p.[UserProductID],0) 
                        ,[OrganizationID] = isnull(p.[OrganizationID],0) 
                        ,[BusinessUnitID] = isnull(I.[BusinessUnitID],0)
                        ,[BusinessUnitName] = isnull(bu.[Name],0) 
                        ,[OwnerUserGroupID] = isnull(p.[OwnerUserGroupID],0) 
                        ,[QuantityOnHand]= (select [dbo].[TotalCalculatedSum] (p.ProductID,''QuantityOnHand'', '+@OwnerUserIDstr+', '+@OrganizationIDstr+', I.BusinessUnitID , '+@InventoryIDstr+'))
                        ,[QuantityBooked] = (select [dbo].[TotalCalculatedSum] (p.ProductID,''QuantityBooked'', '+@OwnerUserIDstr+', '+@OrganizationIDstr+', I.BusinessUnitID, '+@InventoryIDstr+'))
  from dbo.Product p
  left join Inventory I on II.InventoryID = I.InventoryID
  left join dbo.BusinessUnit bu on I.BusinessUnitID=bu.[BusinessUnitID] and bu.[ActiveStatus]=1
  where p.ActiveStatus = 1
  and bu.[ActiveStatus]=1 

这是我的函数,它计算总和

ALTER FUNCTION [dbo].[TotalCalculatedSum] 
  ( 
  @ProductID bigint, 
  @TotalType nvarchar(200), 
  @OwnerUserID bigint, 
  @OrganizationID bigint, 
  @BusinessUnitID bigint, 
  @InventoryID bigint 
  ) 
  RETURNS decimal(32,9) 
  AS 
  BEGIN 
  -- declare the return variable here 
  declare @OutputValue decimal(32,9) 
  Declare @locationValue int =0 

  IF @TotalType = 'QuantityOnHand' 
  BEGIN 
  set @OutputValue = isnull((select sum(ii.[QuantityOnHand]) 
  from dbo.InventoryItems ii, Inventory i 
  where ii.ActiveStatus=1 
  and ii.ProductID = @ProductID 
  and ii.InventoryID = i.InventoryID 
  AND i.OwnerUserGroupID = case @OwnerUserID 
  when 0 then i.OwnerUserGroupID else @OwnerUserID end 
  AND i.OrganizationID = case @OrganizationID 
  when 0 then i.OrganizationID else @OrganizationID end 
  AND i.BusinessUnitID = case @BusinessUnitID 
  when 0 then i.BusinessUnitID else @BusinessUnitID end 
  AND i.InventoryID = case @InventoryID 
  when 0 then i.InventoryID else @InventoryID end), 0.00) 
  END 
  ELSE IF @TotalType = 'QuantityBooked' 
  BEGIN 
  set @OutputValue = isnull((select sum(ii.QuantitySold) 
  from dbo.InventoryItems ii, Inventory i 
  where ii.ActiveStatus=1 
  and ii.ProductID = @ProductID 
  and ii.InventoryID = i.InventoryID 
  AND i.OwnerUserGroupID = case @OwnerUserID 
  when 0 then i.OwnerUserGroupID else @OwnerUserID end 
  AND i.OrganizationID = case @OrganizationID 
  when 0 then i.OrganizationID else @OrganizationID end 
  AND i.BusinessUnitID = case @BusinessUnitID 
  when 0 then i.BusinessUnitID else @BusinessUnitID end 
  AND i.InventoryID = case @InventoryID 
  when 0 then i.InventoryID else @InventoryID end), 0.00) 
  END 
  return @OutputValue 


  END 

1 个答案:

答案 0 :(得分:0)

如您所见,在SELECT语句中调用标量值函数会变慢。首选方法是将标量函数重写为内联表值函数。我没有查看您的特定查询,但本文可能会帮助您找到方法:http://www.databasejournal.com/features/mssql/article.php/3845381/T-SQL-Best-Practices-150-Don146t-Use-Scalar-Value-Functions-in-Column-List-or-WHERE-Clauses.htm