我有一个非常长时间运行,存储过程繁重的程序,因此我想将其更改为每晚运行的作业并更新表,以便用户可以在白天快速运行它。我的问题是它需要参加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
答案 0 :(得分:0)
有一个表单,用户可以在回家之前将其参数放入,并将其保存到数据库中的新表中。更改存储过程以从此新表中获取参数或使用连接和c中的新表。 SP现在不需要将参数发送给它。最后通过Job调用SP。