-1

我需要存储在多个表中的超过 500000 行。用我的逻辑获取所有行。在这种情况下,我编写了一个在 SQL Server 浏览器中成功执行的存储过程,但是当我从 C# 代码运行它时,发生了超时异常。

谁能建议我如何改进我的存储过程?

CREATE PROCEDURE [dbo].[SP_ExtendedPTU]
(
    @SQLForPTU as varchar(MAX)  
)
AS
BEGIN TRAN
--DECLARE 
--@SQLForPTU as varchar(MAX)
--SET @SQLForPTU= 'WHERE  OrderID IN(4233)And OrderType =3'

BEGIN--1
DECLARE 
@ProductionTracingUnitID    as int,
@OrderID    as int,
@OrderType  as smallint,
@ProductID  as int,
@LabLabDipID    as int,
@ColorName  as varchar(255),
@PantonNo as    varchar(127),
@Shade as varchar(4),
@DyeingOrderQty as decimal(30, 17),
@JobOrderQty    as decimal(30, 17),
@ProductionPipeLineQty as decimal(30, 17),
@ProductionFinishedQty as decimal(30, 17),
@DeliveryQty    as decimal(30, 17),
@BuyerID    as int, 
@FactoryID  as int,
@ProductionGraceQty as decimal(30, 17),
@WeightLossGainQty  as decimal(30, 17),
@RateInLBS as decimal(30, 17),
@State  as smallint,
@ProductionLossQty  as decimal(30, 17),
@ReturnQty as decimal(30, 17),
@ActualDeliveryQty  as decimal(30,17),
@ReadyStockInhand as decimal(30, 17),
@JobOrderQtyApproved    as decimal(30, 17),
@OrderNumber as varchar(50),
@FactoryName as varchar(200),
@BuyerName as varchar(200),
@ProductName as varchar(200),
@YetToDelivery as decimal(30,17),
@StockInHand as decimal(30,17),
@YetToProduction as decimal(30,17),
@LCID as int,
@LCNo as varchar(300),
@PIQty as decimal(30,17),
@ChangingQty as decimal(30,17),
@SampleAdjQty as decimal(30,17),
@SampleAdjValue as decimal(30,17),
@MKTPersonID as int, 
@MKTPersonName as varchar(500),
@MerchandiserID as int,
@MerchandiserName as varchar(500),
@AmendmentStatus as smallint,
@AcceptanceValue as decimal(30,17),
@MaturityValue as decimal(30,17),
@BillAcceptanceValue as decimal(30,17),
@BillMaturityValue as decimal(30,17),
@BillAcceptancePercentage  as decimal(30,17),
@BillMaturityPercentage  as decimal(30,17),
@ExportLCValue as decimal(30,17),
@Acceptance as varchar(100),
@Maturity as varchar(100),
@YarnCount as varchar(50),
@PTUDQty  as decimal(30,17),
@ShadeFromOrder as smallint,
@EWYDLRelabNo as varchar(100),
@EWYDLColorNo as varchar(100),
@DeliveryTo as int,
@FactoryPersonnelID as int,
@BuyerPersonnelID as int,
@OrderRcvBy as int,
@OrderState as smallint

CREATE TABLE #TempTableOne(
                            ProductionTracingUnitID int,
                            OrderID int,
                            OrderType smallint,
                            ProductID int,
                            DyeingOrderQty decimal(30,17),
                            JobOrderQty decimal(30,17),
                            ProductionPipeLineQty decimal(30,17),
                            ProductionFinishedQty decimal(30,17),
                            DeliveryQty decimal(30,17),
                            BuyerID int,
                            FactoryID int,
                            ProductionGraceQty decimal(30,17),
                            WeightLossGainQty decimal(30,17),
                            RateInLBS decimal(30,17),
                            ProductionLossQty decimal(30,17),
                            ActualDeliveryQty decimal(30,17),
                            ReadyStockInhand decimal(30,17),
                            OrderNumber varchar(50),
                            FactoryName varchar(200),
                            BuyerName varchar(200),
                            ProductName varchar(200),
                            ColorName varchar(200),
                            LabLabDipID int,
                            ReturnQty decimal(30,17),
                            YetToDelivery decimal(30,17),
                            StockInHand decimal(30,17),
                            YetToProduction decimal(30,17),
                            LCID int,
                            LCNo varchar(300),
                            PIQty decimal(30,17),
                            ChangingQty decimal(30,17),
                            SampleAdjQty decimal(30,17),
                            SampleAdjValue decimal(30,17),
                            MKTPersonID int, 
                            MKTPersonName varchar(500),
                            MerchandiserID int,
                            MerchandiserName varchar(500),
                            AmendmentStatus smallint,
                            Acceptance varchar(100),
                            Maturity varchar(100),
                            YarnCount varchar(50),                          
                            EWYDLRelabNo varchar(50),
                            EWYDLColorNo varchar(50),
                            ShadeFromOrder smallint
                          )

--ProductionTracingUnitID,OrderID,OrderType,ProductID,LabLabDipID,ColorName,PantonNo,EWYDLColorNo,Shade,EWYDLRelabNo,DyeingOrderQty,JobOrderQty,ProductionPipeLineQty,ProductionFinishedQty,DeliveryQty,BuyerID,FactoryID,ProductionGraceQty,WeightLossGainQty,RateInLBS,State,ProductionLossQty,ShadeFromOrder,ReturnQty,ActualDeliveryQty,ReadyStockInhand,JobOrderQtyApproved
DECLARE 
@SQL as varchar(MAX)
SET @SQL=
'
    DECLARE Cur_AB1 CURSOR GLOBAL FORWARD_ONLY KEYSET FOR           
    SELECT ProductionTracingUnitID,OrderID,OrderType,ProductID,DyeingOrderQty,JobOrderQty,ProductionPipeLineQty,ProductionFinishedQty,BuyerID,FactoryID,ProductionGraceQty,WeightLossGainQty,RateInLBS,ProductionLossQty,ActualDeliveryQty,ReadyStockInhand,ColorName,LabLabDipID,ReturnQty,EWYDLRelabNo,EWYDLColorNo,ShadeFromOrder FROM ProductionTracingUnit '+@SQLForPTU+'
'
EXEC (@SQL)

OPEN Cur_AB1
FETCH NEXT FROM Cur_AB1 INTO @ProductionTracingUnitID,@OrderID,@OrderType,@ProductID,@DyeingOrderQty,@JobOrderQty,@ProductionPipeLineQty,@ProductionFinishedQty,@BuyerID,@FactoryID,@ProductionGraceQty,@WeightLossGainQty,@RateInLBS,@ProductionLossQty,@ActualDeliveryQty,@ReadyStockInhand,@ColorName,@LabLabDipID,@ReturnQty,@EWYDLRelabNo,@EWYDLColorNo,@ShadeFromOrder
    WHILE(@@Fetch_Status <> -1)
    BEGIN--2
        SET @LCID=0
        SET @LCNo=''
        SET @PIQty=0
        SET @AcceptanceValue =0
        SET @MaturityValue= 0
        SET @Acceptance= ''
        SET @Maturity =''


        SET @DeliveryQty=@ActualDeliveryQty-@ReturnQty
        SET @YetToDelivery=@JobOrderQty-@ActualDeliveryQty+@ReturnQty
        set @PTUDQty=(select sum(Qty) from PTUDistribution where ProductionTracingUnitID=@ProductionTracingUnitID )
        IF(@PTUDQty>@YetToDelivery)
        BEGIN--sih
            SET @StockInHand =@YetToDelivery
        END --sih
        ELSE
        BEGIN--sih2
            SET @StockInHand =@PTUDQty
        END --sih2          
        SET @YetToProduction=@JobOrderQty-@ReadyStockInhand-@ActualDeliveryQty+@ReturnQty
        IF (@YetToProduction<0)
        BEGIN
            SET @YetToProduction=0
        END

        SET @ChangingQty=0
        SET @SampleAdjQty=0
        SET @SampleAdjValue=0 
        SET @MerchandiserID=0
        SET @MerchandiserName=''
        SET @MKTPersonID =0
        SET @AmendmentStatus=0
        SET @AcceptanceValue =0
        SET @MaturityValue= 0
        SET @Acceptance= ''
        SET @Maturity =''


        SET @MKTPersonName =''
        SET @OrderNumber=''     
        IF(@OrderType=3)
        BEGIN--jam1
            SET @OrderNumber=(SELECT ISNULL(JobCode,'')+' - '+ISNULL(JobNo,'')+' / '+ISNULL(JobYear,'') FROM Job WHERE JobID=@OrderID)
            SELECT @LCID=ISNULL(ExportLCID,0), @LCNo=ISNULL(ExportLCNo,''),@AmendmentStatus=AmendmentStatus,@ExportLCValue=Amount FROM ExportLC WHERE ExportLCID =(SELECT LCID FROM [PI] WHERE PIID=(SELECT PIID FROM Job WHERE JobID=@OrderID))                    
            SELECT @PIQty=ISNULL(SUM(Qty),0), @SampleAdjQty=ISNULL(SUM(AdjQty),0), @SampleAdjValue=ISNULL(SUM(AdjValue),0) FROM PIProducts WHERE PIID=(SELECT PIID FROM Job WHERE JobID=@OrderID) AND ProductID=@ProductID          
            SET @ChangingQty=(SELECT ISNULL(SUM(Qty),0) FROM PIDeliverableProducts WHERE PIID=(SELECT PIID FROM Job WHERE JobID=@OrderID) AND ProductID=@ProductID)                 
            SELECT @MKTPersonID=EWYDLMarketingEmpID, @MerchandiserID=CmsBCPID FROM [PI] WHERE PIID=(SELECT PIID FROM Job WHERE JobID=@OrderID) 
            SET @MerchandiserName=(SELECT ISNULL([Name],'') FROM ContactPersonnel WHERE ContactPersonnelID=@MerchandiserID)         
            SET @MKTPersonName =(SELECT [Name] FROM Employee WHERE EmployeeID=@MKTPersonID)     


            SET @BillAcceptanceValue=(select isnull(sum(Amount),0) from LCbill where EXportLCID=@LCID and [state] in (2,3,4))
            SET @BillMaturityValue =(select isnull(sum(Amount),0) from LCbill where EXportLCID=@LCID and [state] in (5,6,7,8,9,10,12))

            IF(@ExportLCValue>0 and @ExportLCValue is not null)
            BEGIN
                SET @BillAcceptancePercentage  =(@BillAcceptanceValue*100)/@ExportLCValue -- bill Percentage 
                SET @BillMaturityPercentage  =(@BillMaturityValue*100)/@ExportLCValue

                SET @AcceptanceValue=(@ChangingQty*@RateInLBS)*(@BillAcceptancePercentage/100)--Percentage Wise PI Valu         
                SET @MaturityValue=(@ChangingQty*@RateInLBS)*(@BillMaturityPercentage/100)

                IF((@ChangingQty*@RateInLBS)>0 and (@ChangingQty*@RateInLBS) is not null)
                BEGIN
                    SET @AcceptanceValue=(@AcceptanceValue*100)/(@ChangingQty*@RateInLBS)-- PI ValuePercentage
                    SET @MaturityValue=(@MaturityValue*100)/(@ChangingQty*@RateInLBS)
                END

                SET @Acceptance=Convert(varchar(20),(CONVERT(float,round((@AcceptanceValue+@MaturityValue),0)))) +'%'
                SET @Maturity =Convert(varchar(20),(CONVERT(float,round(@MaturityValue,0)))) +'%'
            END

            SET @FactoryName=''
            IF(@FactoryID>0)
            BEGIN--jam3
                SET @FactoryName=(SELECT [Name] FROM Contractor WHERE ContractorID=@FactoryID)
            END--jam3

            SET @BuyerName=''
            IF(@BuyerID>0)
            BEGIN--jam4
                SET @BuyerName=(SELECT [Name] FROM Contractor WHERE ContractorID=@BuyerID)
            END--jam4

        END--jam1
        ELSE
        BEGIN --jam2 IF Sample
            SET @LCID=0
            SET @LCNo=''
            SET @OrderNumber=''
            SET @PIQty=0    
            SET @DeliveryTo=0
            SET @FactoryPersonnelID=0 
            SET @BuyerPersonnelID=0
            SET @OrderRcvBy=0
            SET @ChangingQty=0
            SET @MerchandiserName=''
            SET @MKTPersonName=''
            SET @OrderState=0
            SET @AmendmentStatus=0
            SET @PIQty= (SELECT ISNULL(SUM(Qty),0) FROM SampleOrderDetail WHERE PTUID=@ProductionTracingUnitID)
            SET @ChangingQty=@PIQty
            SELECT @OrderNumber=ISNULL(SampleOrderNo,''), @DeliveryTo=ISNULL(DeliveryTo,0),@FactoryPersonnelID=ISNULL(FactoryPersonnelID,0),@BuyerPersonnelID=ISNULL(BuyerPersonnelID,0),@OrderRcvBy=ISNULL(OrderRcvBy,0),@OrderState=ISNULL(OrderState,0)  FROM SampleOrder WHERE SampleOrderID=@OrderID
            SET @AmendmentStatus=@OrderState
            IF(@DeliveryTo=3)
            BEGIN
                SET @MerchandiserName=(SELECT ISNULL([Name],'') FROM ContactPersonnel WHERE ContactPersonnelID=@FactoryPersonnelID)     
            END

            IF(@DeliveryTo=2)
            BEGIN
                SET @MerchandiserName=(SELECT ISNULL([Name],'') FROM ContactPersonnel WHERE ContactPersonnelID=@BuyerPersonnelID)
            END
            SET @MKTPersonName =(SELECT [Name] FROM Employee WHERE EmployeeID=@OrderRcvBy)      

            IF(@DeliveryTo=3)
            BEGIN
                SET @FactoryName=(SELECT [Name] FROM Contractor WHERE ContractorID=@FactoryID)
            END

            IF(@DeliveryTo=2)
            BEGIN
                SET @FactoryName=(SELECT [Name] FROM Contractor WHERE ContractorID=@BuyerID)
            END     

            SET @BuyerName=''
            IF(@BuyerID>0)
            BEGIN--jam4
                SET @BuyerName=(SELECT [Name] FROM Contractor WHERE ContractorID=@BuyerID)
            END--jam4
        END--jam2

        SET @ProductName=''
        SET @YarnCount =''
        SELECT @ProductName=('['+ Code+ '] '+ [Name]), @YarnCount =[Count]  FROM Yarncategory WHERE YarncategoryID=@ProductID       

        INSERT INTO #TempTableOne Values(ISNULL(@ProductionTracingUnitID,0),ISNULL(@OrderID,0),ISNULL(@OrderType,0),ISNULL(@ProductID,0),ISNULL(@DyeingOrderQty,0),ISNULL(@JobOrderQty,0),ISNULL(@ProductionPipeLineQty,0),ISNULL(@ProductionFinishedQty,0),ISNULL(@DeliveryQty,0),ISNULL(@BuyerID,0),ISNULL(@FactoryID,0),ISNULL(@ProductionGraceQty,0),ISNULL(@WeightLossGainQty,0),ISNULL(CONVERT (decimal(18,2),@RateInLBS),0),ISNULL(@ProductionLossQty,0),ISNULL(@ActualDeliveryQty,0),ISNULL(@ReadyStockInhand,0),ISNULL(@OrderNumber,''),ISNULL(@FactoryName,''),ISNULL(@BuyerName,''),ISNULL(@ProductName,''),ISNULL(@ColorName,''),ISNULL(@LabLabDipID,0),ISNULL(@ReturnQty,0),ISNULL(@YetToDelivery,0),ISNULL(@StockInHand,0),ISNULL(@YetToProduction,0),ISNULL(@LCID,0),ISNULL(@LCNo,''),ISNULL(@PIQty,0),ISNULL(@ChangingQty,0),ISNULL(@SampleAdjQty,0),ISNULL(@SampleAdjValue,0),ISNULL(@MKTPersonID,0),ISNULL(@MKTPersonName,''),ISNULL(@MerchandiserID,0),ISNULL(@MerchandiserName,''),ISNULL(@AmendmentStatus,0),ISNULL(@Acceptance,''),ISNULL(@Maturity,''),ISNULL(@YarnCount,''),ISNULL(@EWYDLRelabNo,''),ISNULL(@EWYDLColorNo,''),ISNULL(@ShadeFromOrder,0))
FETCH NEXT FROM Cur_AB1 INTO @ProductionTracingUnitID,@OrderID,@OrderType,@ProductID,@DyeingOrderQty,@JobOrderQty,@ProductionPipeLineQty,@ProductionFinishedQty,@BuyerID,@FactoryID,@ProductionGraceQty,@WeightLossGainQty,@RateInLBS,@ProductionLossQty,@ActualDeliveryQty,@ReadyStockInhand,@ColorName,@LabLabDipID,@ReturnQty,@EWYDLRelabNo,@EWYDLColorNo,@ShadeFromOrder
END--2
CLOSE Cur_AB1
DEALLOCATE Cur_AB1
SELECT * FROM #TempTableOne Order By OrderID
--Group By Product
SELECT ProductID,ProductName, YarnCount,  SUM(PIQty) as PIQty, SUM(ChangingQty) AS ChangingQty, SUM(SampleAdjQty) AS SampleAdjQty, SUM(SampleAdjValue) as SampleAdjValue, SUM(DyeingOrderQty) as DyeingOrderQty,SUM(JobOrderQty)AS JobOrderQty,SUM(ProductionPipeLineQty)as ProductionPipeLineQty,SUM(ProductionFinishedQty) as ProductionFinishedQty,SUM(DeliveryQty)as DeliveryQty,SUM(ProductionGraceQty)AS ProductionGraceQty,SUM(WeightLossGainQty) as WeightLossGainQty,SUM(ProductionLossQty)as ProductionLossQty,SUM(ActualDeliveryQty)as ActualDeliveryQty,SUM(ReadyStockInhand)as ReadyStockInhand, SUM(ReturnQty) AS ReturnQty,SUM(YetToDelivery)AS YetToDelivery,SUM(StockInHand)AS StockInHand,SUM(YetToProduction)AS YetToProduction  FROM #TempTableOne GROUP BY ProductID,ProductName,YarnCount Order By ProductID
--Group By Factory
SELECT FactoryID,FactoryName,SUM(PIQty) as PIQty, SUM(ChangingQty) AS ChangingQty, SUM(SampleAdjQty) AS SampleAdjQty, SUM(SampleAdjValue) as SampleAdjValue, SUM(DyeingOrderQty) as DyeingOrderQty,SUM(JobOrderQty)AS JobOrderQty,SUM(ProductionPipeLineQty)as ProductionPipeLineQty,SUM(ProductionFinishedQty) as ProductionFinishedQty,SUM(DeliveryQty)as DeliveryQty,SUM(ProductionGraceQty)AS ProductionGraceQty,SUM(WeightLossGainQty) as WeightLossGainQty,SUM(ProductionLossQty)as ProductionLossQty,SUM(ActualDeliveryQty)as ActualDeliveryQty,SUM(ReadyStockInhand)as ReadyStockInhand, SUM(ReturnQty) AS ReturnQty,SUM(YetToDelivery)AS YetToDelivery,SUM(StockInHand)AS StockInHand,SUM(YetToProduction)AS YetToProduction FROM #TempTableOne GROUP BY FactoryID,FactoryName
--Group By Order    
SELECT OrderID,OrderNumber,LCNo,FactoryID,FactoryName,BuyerID,BuyerName,SUM(PIQty) AS PIQty,SUM(ChangingQty) AS ChangingQty,SUM(SampleAdjQty) AS SampleAdjQty,SUM(SampleAdjValue) AS SampleAdjValue,MKTPersonID,MKTPersonName,MerchandiserID,MerchandiserName,AmendmentStatus,Acceptance,Maturity,SUM(DyeingOrderQty) as DyeingOrderQty,SUM(JobOrderQty)AS JobOrderQty,SUM(ProductionPipeLineQty)as ProductionPipeLineQty,SUM(ProductionFinishedQty) as ProductionFinishedQty,SUM(DeliveryQty)as DeliveryQty,SUM(ProductionGraceQty)AS ProductionGraceQty,SUM(WeightLossGainQty) as WeightLossGainQty,SUM(ProductionLossQty)as ProductionLossQty,SUM(ActualDeliveryQty)as ActualDeliveryQty,SUM(ReadyStockInhand)as ReadyStockInhand, SUM(ReturnQty) AS ReturnQty,SUM(YetToDelivery)AS YetToDelivery,SUM(StockInHand)AS StockInHand,SUM(YetToProduction)AS YetToProduction FROM #TempTableOne GROUP BY OrderID,OrderNumber,OrderNumber,LCNo,FactoryID,FactoryName,BuyerID,BuyerName,MKTPersonID,MKTPersonName,MerchandiserID,MerchandiserName,AmendmentStatus,Acceptance,Maturity
--Default View
SELECT OrderID,OrderNumber,LCNo,FactoryID,FactoryName,BuyerID,BuyerName,ProductID,ProductName,YarnCount,PIQty,ChangingQty,SampleAdjQty,SampleAdjValue,RateInLBS,MKTPersonID,MKTPersonName,MerchandiserID,MerchandiserName,AmendmentStatus,Acceptance,Maturity, SUM(DyeingOrderQty) as DyeingOrderQty,SUM(JobOrderQty)AS JobOrderQty,SUM(ProductionPipeLineQty)as ProductionPipeLineQty,SUM(ProductionFinishedQty) as ProductionFinishedQty,SUM(DeliveryQty)as DeliveryQty,SUM(ProductionGraceQty)AS ProductionGraceQty,SUM(WeightLossGainQty) as WeightLossGainQty,SUM(ProductionLossQty)as ProductionLossQty,SUM(ActualDeliveryQty)as ActualDeliveryQty,SUM(ReadyStockInhand)as ReadyStockInhand, SUM(ReturnQty) AS ReturnQty,SUM(YetToDelivery)AS YetToDelivery,SUM(StockInHand)AS StockInHand,SUM(YetToProduction)AS YetToProduction  FROM #TempTableOne GROUP BY OrderID,OrderNumber,LCNo,FactoryID,FactoryName,BuyerID,BuyerName,ProductID,ProductName,YarnCount,PIQty,ChangingQty,SampleAdjQty,SampleAdjValue,RateInLBS,MKTPersonID,MKTPersonName,MerchandiserID,MerchandiserName,AmendmentStatus,Acceptance,Maturity   
DROP TABLE #TempTableOne
END--1
COMMIT TRAN
4

3 回答 3

1

这里有很多问题。如果编写得当,这个过程应该可以在大约 15 秒内轻松运行,具体取决于您的索引。在深入研究之前,我可以给你的提示如下:

首先,在进行批量处理时,唯一可以接受使用游标的情况是在批量处理中对更新进行分区。换句话说,永远不要使用需要为要更新的每条记录进行迭代的游标。整个过程需要迭代 500,000 次,这将非常缓慢。而是使用临时表将数据插入,然后使用该表执行更新。可以使用临时索引来索引临时表,如下面的代码所示。确保在 WHERE 子句中使用的任何字段都被索引,无论是对于您的临时表还是您的活动表。

CREATE TABLE #Temp2 (
    ProductionTracingUnitID int,
    OrderID int,
    OrderType smallint,
    ProductID int,
    DyeingOrderQty  decimal(30, 17),
    JobOrderQty     decimal(30, 17),
    ProductionPipeLineQty  decimal(30, 17),
    ProductionFinishedQty  decimal(30, 17),
    BuyerID     int, 
    FactoryID   int,
    ProductionGraceQty  decimal(30, 17),
    WeightLossGainQty   decimal(30, 17),
    RateInLBS  decimal(30, 17),
    ProductionLossQty   decimal(30, 17),
    ActualDeliveryQty   decimal(30,17),
    ReadyStockInhand  decimal(30, 17),
    ColorName   varchar(255),
    LabLabDipID     int,
    ReturnQty  decimal(30, 17),
    EWYDLRelabNo  varchar(100),
    EWYDLColorNo  varchar(100),
    ShadeFromOrder  smallint
)
CREATE NONCLUSTERED INDEX #IX_Temp2_1 ON #Temp2(ProductionTracingUnitID)
CREATE NONCLUSTERED INDEX #IX_Temp2_2 ON #Temp2(OrderID)
CREATE NONCLUSTERED INDEX #IX_Temp2_3 ON #Temp2(ProductID)

DECLARE @SQL as varchar(MAX)
SET @SQL=
'
    SELECT ProductionTracingUnitID,OrderID,OrderType,ProductID,DyeingOrderQty,JobOrderQty,ProductionPipeLineQty,ProductionFinishedQty,BuyerID,FactoryID,ProductionGraceQty,
        WeightLossGainQty,RateInLBS,ProductionLossQty,ActualDeliveryQty,ReadyStockInhand,ColorName,LabLabDipID,ReturnQty,EWYDLRelabNo,EWYDLColorNo,ShadeFromOrder 
    FROM ProductionTracingUnit '+@SQLForPTU
INSERT INTO #Temp2 (ProductionTracingUnitID, OrderID, OrderType, ProductID, DyeingOrderQty, JobOrderQty, ProductionPipeLineQty, 
        ProductionFinishedQty, BuyerID, FactoryID, ProductionGraceQty, WeightLossGainQty, RateInLBS, ProductionLossQty, ActualDeliveryQty,
        ReadyStockInhand, ColorName, LabLabDipID, ReturnQty, EWYDLRelabNo, EWYDLColorNo, ShadeFromOrder)
EXEC (@SQL)

其次,在做批量处理时,避免使用需要每行执行的子查询。在最好的情况下,以下行会非常慢:

SELECT @LCID=ISNULL(ExportLCID,0), @LCNo=ISNULL(ExportLCNo,''),@AmendmentStatus=AmendmentStatus,@ExportLCValue=Amount 
FROM ExportLC WHERE ExportLCID =(SELECT LCID FROM [PI] WHERE PIID=(SELECT PIID FROM Job WHERE JobID=@OrderID))                    

考虑使用连接重新表述,如下所示:

SELECT @LCID=ISNULL(ExportLCID,0), @LCNo=ISNULL(ExportLCNo,''),@AmendmentStatus=AmendmentStatus,@ExportLCValue=Amount 
FROM ExportLC e, [PI] p, Job j
WHERE e.ExportLCID = p.LCID
AND p.PIID = j.PIID
AND j.JobID = @OrderID

在不使用游标的情况下重写过程,这看起来更像是:

UPDATE #Temp2 SET LCID = ISNULL(ExportLCID, 0), LCNo = ISNULL(ExportLCNo, 0), ...
FROM #Temp2 t, ExportLC e, [PI] p, Job j
WHERE e.ExportLCID = p.LCID
AND p.PIID = j.PIID
AND j.JobID = t.OrderID

要让这一切正常工作需要做很多工作,而且我很难为这样一个复合过程创建一个测试环境。但是,我认为这应该给你足够的继续。如果您遇到困难,请告诉我。

于 2012-05-02T09:36:09.547 回答
0

如果您要解析 500,000 行,则游标是非首发。这将导致各种问题,并且随着数据的增长,它会变得越来越慢。有几种方法可以实现更好的性能。

1) 如果可能,在一夜之间获取数据 - 即使用 SQL 作业将数据扁平化到快照表中

2)在批量选择中获取尽可能多的数据 - 即不是在循环中逐行插入临时表,您可以执行查询以获取特定列所需的所有数据

3) 如果你不能在一夜之间做到这一点,并且必须始终这样做,我建议将其分解为谨慎的存储过程并从你的 C# 代码中循环。这样您就可以向您的用户提供反馈——也许以进度条的形式。这不会超时,只要用户知道正在计算某些东西,他们大概知道他们必须等待多长时间,并且如果他们有机会退出,那么花费多长时间并不重要。想要。

于 2012-05-02T07:08:23.613 回答
0

您可以使用 SQL Server 中的执行计划来识别瓶颈。另外请尽量避免使用游标,如果临时表包含大量数据,请创建普通表而不是创建#table

于 2012-05-02T06:06:44.403 回答