我有一个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
答案 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