sql存储过程 - 我想将它更改为一个作业,但它有参数

时间:2016-04-20 13:53:09

标签: sql-server performance tsql query-optimization

我有一个非常长时间运行,存储过程繁重的程序,因此我想将其更改为每晚运行的作业并更新表,以便用户可以在白天快速运行它。我的问题是它需要参加LEFT JOIN,所以我不知道如何做到这一点。我试图从连接中删除参数并只记录所有记录,但第一个问题是这些左连接是使用group by子句连接到表值函数(所以它现在有大量的记录)当我这样做时,它崩溃了整个服务器。我将发布部分存储过程,让您了解我现在正在做什么。

- 或者,我会采取一个可以将我的查询性能从2分钟改为10秒的答案。 :)

- 顺便说一下,另一件让这个查询变慢的事情就是函数正在查询链接的服务器......

create PROC [dbo].[mySP]
        @FromDate DateTime,
        @ToDate DateTime = NULL,
        @Style NVARCHAR(max),
        @ItemType  NVARCHAR(300),
        @ItemCode NVARCHAR(150)= null,
        @ItemsNotSold INT,
        @MultiplyUsage DECIMAL(18,4),
        @SParts BIT, 
        @vendorId nvarchar(50),
        @currentPage int, 
        @largeOrderSoNumbers nvarchar(300) = null,
        @excludeprojTag BIT,
        @hasOrderQty BIT = null,
        @createPO BIT = null,
        @excludeTestOrders BIT = null,
        @refresh BIT = null,
        @userid int = null,
        @positiveOverUse BIT = null
AS


SELECT @FROMDATE = @FROMDATE
,@ToDate=@ToDate
,@Style=@Style
,@ItemType=@ItemType
,@ItemCode=@ItemCode
,@ItemsNotSold=@ItemsNotSold
,@MultiplyUsage=@MultiplyUsage
,@SParts=@SParts
,@vendorId=@vendorId
,@currentPage=@currentPage
,@largeOrderSoNumbers=@largeOrderSoNumbers
,@excludeprojTag=@excludeprojTag
,@hasOrderQty =@hasOrderQty
,@createPO =@createPO
,@excludeTestOrders =@excludeTestOrders
,@refresh =@refresh
,@userid =@userid
,@positiveOverUse=@positiveOverUse

DECLARE @amountPerPage int = 400;
DECLARE @startingPoint int = (@currentpage - 1) * @amountPerPage 

SET @TODATE = NULLIF(@TODATE,'1/1/4000');
SET @ITEMCODE = NULLIF(@ITEMCODE,'');
SET @largeOrderSoNumbers = NULLIF(@LARGEORDERSONUMBERS,'');


BEGIN
    IF @Style = '-1'
        SET @Style = NULL
    IF @ItemType = '-1'
        SET @ItemType = NULL
END




SELECT
    ISNULL(c.NewQB_ListID,iit.ListID) ListID,   
    (select salesdesc from iteminventory i where i.listid = ISNULL(c.NewQB_ListID,iit.ListID)) as SalesDesc,
    isnull(inl.linename,'') + isnull(c.NewName,Name)    as ItemCode ,
    max(il.CubicMeterKD) as CubicMeterKD,

    sum(CONVERT(decimal(18,4),inl.Quantity) )
    - sum(CONVERT(decimal(18,4),inl.qtyRuleTag))
+ CONVERT(decimal(18,4),isnull(ai.qty,0))
 -CONVERT(decimal(18,4),isnull(ai.QtyRuleTag,0))   
  AS TotalQtyUesd,  
    sum(convert(decimal(18,4),isnull(inl.QtyRuleTag,0))) 
     as QtyUsedWithProjectTag,
    Convert(decimal(18,4),QuantityOnHand) as OnHand,
    CONVERT(int,ISNULL(EzQtyOnSO.Qty,0)) as OnSalesOrder,
    CONVERT(int,ISNULL(EzQtyAnyStatus.QtyLgO,0))as OnLgOrder,
    Convert(decimal(18,4),QuantityOnOrder) as OnPO,
    Convert(decimal(18,4),isnull(LargePO.lgOrderQtyOnPO,0)) as lgOrderQtyOnPO ,
    fl.LineName
    INTO #Q
FROM 
    iteminventory iit 

LEFT JOIN Lines fl
        ON iit.ParentRef_ListID = QB_LisiID 

LEFT JOIN tb_ItemList il
        ON iit.ListID = il.QBListID 


LEFT JOIN InlSales(@FromDate,@ToDate, @excludeprojtag, @excludeTestOrders) INL 
        ON IIT.LISTID = INL.ITEMREF_LISTID  


LEFT JOIN tb_CombinedItems c
        ON iit.ListID = c.ListID 

LEFT JOIN [QuantityInvoice](@FromDate, @ToDate,@excludeprojTag,@excludeTestOrders) as ai 
        ON ai.QBID = iit.ListID 

LEFT JOIN   fn_QuantityOnSalesOrder(@excludeTestOrders) AS EzQtyOnSO 
        ON iit.ListID = EzQtyOnSO.QBID

LEFT JOIN QuantityAnyStatus(@largeOrderSoNumbers, @excludeprojTag) AS EzQtyAnyStatus 
        ON iit.ListID = EzQtyAnyStatus.QBID

LEFT JOIN dbo.[FN_LargePO](@excludeTestOrders) LargePO --WITH (nolock) 
        ON LargePO.QBID = iit.ListID

WHERE 
    (@Style is null or ISNULL(c.ParentListID,ParentRef_ListID) in (SELECT Value From fn_MultiValueParameter(@Style))) AND
    (@ItemType is null or ItemTypeCode in (SELECT Value From fn_MultiValueParameter(@ItemType))) AND
    (@ItemCode is null or il.ItemCode like '%' + @ItemCode + '%') AND
    (IsActive = 1 OR c.ListID IS NOT NULL)

GROUP BY 
    ISNULL(c.NewQB_ListID,iit.ListID),
    ISNULL(c.NewName,Name),
    inl.LineName,
    QuantityOnHand,
    iit.QuantityOnOrder,
    CONVERT(int,ISNULL(EzQtyOnSO.Qty,0)),
    fl.LineName,
    CONVERT(decimal(18,4),isnull(ai.qty,0)),
    Convert(decimal(18,4),isnull(LargePO.lgOrderQtyOnPO,0)),
    CONVERT(int,ISNULL(EzQtyAnyStatus.QtyLgO,0)),
CONVERT(decimal(18,4),isnull(ai.QtyRuleTag,0))



IF @ItemsNotSold = 1
    BEGIN 
        DELETE FROM #Q
        WHERE isnull(TotalQtyUesd,0) <> 0 
    END
IF @ItemsNotSold = 2
    BEGIN 
        DELETE FROM #Q
        WHERE isnull(TotalQtyUesd,0) = 0
    END 



    SELECT 
        q.ListID,
        q.SalesDesc,
        q.ItemCode,
        MAX(isnull(q.CubicMeterKD,0)) as CubicMeterKD,
        SUM(q.TotalQtyUesd)
         TotalQtyUesd,
        SUM(q.QtyUsedWithProjectTag) as QtyUsedWithProjectTag,
        SUM(q.OnHand)  OnHand,
        SUM(q.OnSalesOrder) OnSalesOrder,
        SUM(q.OnLgOrder) OnLgOrder,
        SUM(q.OnPO) 
        - isnull(SUM(q.lgOrderQtyOnPO),0)  
        OnPO,
        SUM(q.lgOrderQtyOnPO) as lgOrderQtyOnPO,
        LineName
        INTO #QTY  
    FROM 
        #Q q 

    GROUP BY 
        q.ListID,
        q.salesdesc,
        q.ItemCode,
        q.LineName

        ;WITH Results AS
(
        SELECT 
            isnull(P.listid,'') as ListID,
            isnull(P.SalesDesc,'') as SalesDesc,
            isnull(P.itemcode,'')  as ItemCode,
            ISNULL(CubicMeterKD,0) AS CubicMeterKD,
            isnull(TotalQtyUesd,0)  as TotalQtyUsed,
            isnull(QtyUsedWithProjectTag,0) as QtyUsedWithProjectTag,
            isnull(onhand,0) as OnHand,
            isnull((OnHand - OnSalesOrder - OnLgOrder),0) as available, 
            isnull(OnLgOrder,0) as OnLgOrder,       
            isnull(OnPO,0) as OnPo,
            isnull(lgOrderQtyOnPO,0) as lgOrderQtyOnPO, 
            isnull(((OnHand - OnSalesOrder) + OnPO) ,0) AS [AvailableAndOnPo],
            isnull((TotalQtyUesd  * @MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO),0) AS [AvlOnPOminusUsed],
            isnull((((TotalQtyUesd * @MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO)) / CASE WHEN TotalQtyUesd > 0 THEN TotalQtyUesd END)*100,0) AS PctOver
            ,isnull(linename,0) as LineName,
            isnull((select price from qbdb.dbo.tb_iteminfodetail where vendorlistid = @vendorid and itemcode =isnull(P.itemcode,'')),0.0) as price
            ,isnull(pod.qtytoReOrder,0) as qtyToReOrder
            ,isnull(pod.qtytoOrder,0) as qtyToOrder
            ,isnull(pod.includePO,0) as includePO
            ,ROW_NUMBER() OVER (ORDER BY ITEMCODE) AS RowNum

        FROM  #qty AS p
        left join dbo.purchaseorderpreliminarydetails pod on pod.listid = P.listid and pod.deleteFlag = 0
        and headerid = (select top 1 headerid from purchaseorderpreliminary where deleteFlag = 0)
        WHERE 

        CASE WHEN @positiveOverUse = 1 THEN 
        isnull((((TotalQtyUesd * @MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO)) / CASE WHEN TotalQtyUesd > 0 THEN TotalQtyUesd END)*100,0) 
        ELSE 1 END >0

        AND
        case when  @hasOrderQty = 1 then isnull(pod.QtyToReOrder,0) else 1 end > 0 
        and 

        CASE WHEN @SPARTS = 1 THEN CASE WHEN 
        ItemCode IN (
                        'APP',
                        'CD',
                        '-S',
                        'L0',
                        'L/42',
                        'L01',
                        'Lfrgs2',
                        'Lfad2',
                        'Sfasdf9',
                        'SdafdsA',
                        'Sfasdf3',
                        'Sasdf6',
                        'asdf0',
                        'Sf6',
                        'fasdfadf2',
                        'fasdfasdf',
                        'S2236',
                        'S12342',
                        'Sdf 30',
                        'SdfE 36',
                        'fgsfgs',
                        'fasdf-fdasf',
                        'fadf',
                        'fasdf-fasdf',
                        'sdaf',
                        'adf 11"',
                        'fda 14"',
                        'fdas 24"') THEN 1 ELSE 0 END ELSE 1 END = 1
    )
    SELECT (select count(rownum) from results) as totalItems,* FROM Results WHERE 
    rownum between @startingPoint + 1 and @startingPoint + @amountPerPage

1 个答案:

答案 0 :(得分:0)

有一个表单,用户可以在回家之前将其参数放入,并将其保存到数据库中的新表中。更改存储过程以从此新表中获取参数或使用连接和c中的新表。 SP现在不需要将参数发送给它。最后通过Job调用SP。