0

下面的脚本需要10 多个小时才能执行.. 它包含three nested cursors并且我认为它们是罪魁祸首。我搜索了很多以替换光标或提高脚本的性能。并找到了很多方法来删除cursor. 例如简单的集合连接操作、Marge 操作等。但我仍然无法在我的脚本中实现它们。请看一下剧本并给出一些意见

- 在不影响输出的情况下,是否可以删除内部光标

- 如果可能的话怎么办?如果可能,请提供一些代码

    DECLARE @Start_Date Date = '1990-01-01'
DECLARE @End_Date Date = '2012-12-12'
DECLARE @Company_ID int = 180

declare @BP_ID [int]
DECLARE All_Client_Bp_Id CURSOR STATIC  FOR
SELECT TOP 50 Bp_id FROM  Client        --Take All Client's BPID 
OPEN All_Client_Bp_Id
FETCH NEXT FROM All_Client_Bp_Id
    INTO @BP_ID
WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @acrdint MONEY
    DECLARE @acrdSrv MONEY
    DECLARE @MaxMargLimit MONEY
    DECLARE @ForceLimit MONEY
    DECLARE @WarningLimit MONEY
    DECLARE @MarginLimit DECIMAL(5,2)
    select @MaxMargLimit=Highest_Margin_Limit*100000,@ForceLimit=Force_Sell_Limit,@WarningLimit=Margin_Warning_Limit, @MarginLimit = Margin_Limit 
    from Client_Margin_Constraints c
        inner join (select Bp_id, max(Update_Date) as updt 
                    from Client_Margin_Constraints 
                    where Update_Date <= @End_Date and Bp_id = @BP_ID and Company_ID = @Company_ID 
                    group by Bp_id)  b  
                    on c.Bp_id = b.Bp_id and c.Update_Date = b.updt

    DELETE FROM Temp_Portfolio
    INSERT  INTO    Temp_Portfolio (Client_BP_ID, tran_date, Instrument_ID, Is_Buy, Quantity, Amount, Commission, Rate, Category,Tax_Amount)
        SELECT  t.Client_BP_ID, t.tran_date, t.Instrument_ID, t.Is_Buy, t.Quantity, t.Amount, t.Commission,
                t.Rate, t.Category, t.Tax_Amount
        FROM    All_Share_Txn   t
        WHERE t.Client_BP_ID = @BP_ID

    DECLARE @Instrument_Id int,
                @bqty int,
                @bamt MONEY,
                @brate MONEY,
                @srate MONEY,
                @rprofit MONEY,
                @mslbqty int,
                @BCost MONEY,
                @SCost MONEY,
                @BCqty int,
                @SCqty int,
                @B_Or_S CHAR(1),
                @CDBL_Type CHAR(1),
                @Qty INT,
                @MktPrice MONEY,
                @Amount MONEY,
                @Commission MONEY,
                @TDATE SMALLDATETIME,
                @DES CHAR(30),
                @TotalProfit MONEY,
                @Category CHAR(1)
        SET @TotalProfit = 0

        DECLARE CUR_SHARE CURSOR STATIC  FOR
           SELECT DISTINCT Instrument_Id 
           FROM  Temp_Portfolio 
        OPEN CUR_SHARE
        FETCH NEXT FROM CUR_SHARE
            INTO @Instrument_Id
        WHILE @@FETCH_STATUS = 0
        BEGIN   
            SET @bqty = 0
            SET @bamt = 0
            SET @brate = 0
            SET @srate = 0
            SET @rprofit = 0
            SET @mslbqty = 0
            SET @BCost = 0
            SET @SCost = 0
            SET @BCqty = 0
            SET @SCqty = 0
            DECLARE CUR_COST CURSOR STATIC  FOR
                SELECT Is_buy,Quantity,rate,Amount,Commission,Tran_date
                FROM  Temp_Portfolio 
                WHERE Client_Bp_id=@BP_ID and Instrument_Id=@Instrument_Id
                ORDER BY Tran_date,Is_buy desc,Category
            OPEN CUR_COST
            FETCH NEXT FROM CUR_COST
                INTO @B_Or_S,@Qty,@MktPrice,@Amount,@Commission,@TDATE
            WHILE @@FETCH_STATUS = 0
            BEGIN
                IF @B_Or_S='1'
                    BEGIN
                    SET @bqty = @bqty + @Qty
                    SET @bamt = @bamt + @Amount + @Commission
                    IF @bqty > 0
                        SET @brate = @bamt/@bqty
                    END 
                ELSE IF @B_Or_S='0' 
                    BEGIN
                    SET @srate = @MktPrice
                    IF @TDATE > @Start_Date and @TDATE <= @End_Date
                        BEGIN
                        SET @rprofit = @rprofit + ((@srate - @brate) * @Qty) - @Commission
                        SET @BCqty = @BCqty + @Qty
                        SET @SCqty = @SCqty + @Qty
                        SET @BCost = @BCost + (@Brate * @Qty) 
                        SET @SCost = @SCost + (@Srate * @Qty) - @Commission 
                        END         
                    SET @bamt = @bamt - (@brate * @Qty)
                    SET @bqty = @bqty - @Qty
                    END
                FETCH NEXT FROM CUR_COST
                    INTO @B_Or_S,@Qty,@MktPrice,@Amount,@Commission,@TDATE
            END

            SET @TotalProfit=@TotalProfit+@rprofit
            CLOSE CUR_COST
            DEALLOCATE  CUR_COST
            FETCH NEXT FROM CUR_SHARE
            INTO @Instrument_Id
        END
        CLOSE CUR_SHARE
        DEALLOCATE CUR_SHARE

    --Select @TotalProfit as Realised_Gain
-- Equity, Purchase Power Calculation
        DECLARE @Equity_All MONEY
        DECLARE @Equity_Margin MONEY
        DECLARE @Current_Balance MONEY
        DECLARE @temp_Purchase_Power_1 MONEY
        DECLARE @temp_Purchase_Power_2 MONEY
        DECLARE @Purchase_Power MONEY

        --Balance
        select  @Current_Balance = sum((case when a.Is_Share_TXN='1' and a.Is_Debit='1' then -a.amount when a.Is_Share_TXN='1' and a.Is_Debit='0' then a.amount when a.Is_Share_TXN='0' and a.Is_Debit='0' then a.amount when a.Is_Share_TXN='0' and a.Is_Debit='1' then -a.amount end) -a.Commission)  
        from Client_Transaction a where a.Client_Bp_id = @BP_ID and a.Transaction_Date < @End_Date and a.Company_Id=@Company_Id
        group by a.Client_Bp_id--dbo.get_Current_Balance(@BP_ID, @End_Date, @Company_ID)

        --Equity Margin
        SELECT @Equity_Margin = SUM(CASE WHEN t_Margin.Is_Marginable_Securities = 'True' Then t_Margin.Total_Quantity * t_Margin.Market_price END),
                @Equity_All = SUM(t_Margin.Total_Quantity * t_Margin.Market_price)
                                FROM
                                (
                                select t2.Is_Marginable_Securities, --t3.Bp_Code as Client_Code,t3.Bp_Name as Client_Name,t4.Bo_Id_DSE,t1.Instrument_ID,
                                   sum(case when Is_buy='True' then Quantity when Is_buy='False'  then -quantity end) as Total_Quantity,
                                   --sum(case when ISNULL(t1.Mature_Date_Share,t1.tran_date) <= @Transaction_Date then (case Is_buy when '1' then quantity when '0' then -quantity end) else 0 end) as Free_Quantity,
                                   INDX.Closing_Price AS Market_price
                                from dbo.View_All_Share_Transactions_with_PledgeUnpledge t1 left outer join Instrument t2 on t1.Instrument_Id=t2.Instrument_ID
                                                                                        left outer join (
                                                                                                            select Closing_Price from Index_Price ip
                                                                                                            where ip.Txn_Date=(select MAX(Txn_Date) from Index_Price ip2 where ip2.Instrument_Id=ip.Instrument_Id)
                                                                                                        ) INDX
                                                                                                        ON t1.Instrument_ID = INDX.Closing_Price
                                where Client_Bp_id = @BP_ID and t1.Instrument_ID is not null  and tran_date <=@End_Date and t1.Is_Pledge_Unpledge = 'False'
                                group by t1.Instrument_ID,t2.Is_Marginable_Securities, INDX.Closing_Price
                                having sum(case when Is_buy='True' then Quantity when Is_buy='False'  then -quantity end)<> 0

                                ) t_Margin              --dbo.get_Equity_Margin(@BP_ID, @End_Date, @Company_ID)
        SET @Equity_Margin = @Equity_Margin + @Current_Balance                      
        SET @Equity_All = @Equity_All + @Current_Balance

        SET @temp_Purchase_Power_1 = (@Equity_Margin * (@MarginLimit / 100)) + @Current_Balance
        SET @temp_Purchase_Power_2 = ISNULL(@MaxMargLimit,0) + ISNULL(@Current_Balance,0)

        IF (@temp_Purchase_Power_1 < @temp_Purchase_Power_2)
            BEGIN
                SET @Purchase_Power = @temp_Purchase_Power_1
            END
        ELSE
            BEGIN
                SET @Purchase_Power = @temp_Purchase_Power_2
            END
    INSERT Client_Account_Balance (
                                    BP_ID,
                                    Equity_All,
                                    Equity_Margin,
                                    Purchase_Power,
                                    Margin_Ratio,
                                    Total_Deposit,
                                    Withdraw,
                                    Charges,
                                    Current_Balance,
                                    Aaccured_Charges,
                                    Max_Margin_LImit,
                                    Margin_Limit,
                                    Realised_Gain,
                                    Company_ID,
                                    Created_By,
                                    Updated_By
                                    )
    SELECT @BP_ID, @Equity_All,@Equity_Margin ,@Purchase_Power ,

          CASE WHEN (@Current_Balance - ISNULL(@acrdSrv,0)) != 0 THEN  (@Equity_Margin - @Current_Balance) * (-100)/(@Current_Balance - ISNULL(@acrdSrv,0)) ELSE 0 END,
         TDEP,TWDRAW,TCHARGES,BALANCE,ACC_CHARGE,@MaxMargLimit ,@MarginLimit,
         @TotalProfit,
         180,1,1
         FROM 
        (SELECT SUM(DEPOSITE) AS TDEP,SUM(WDRAW) AS TWDRAW,SUM(CHARGES) AS TCHARGES,SUM(DEBCRED-Commission) AS BALANCE,SUM(ISNULL(@acrdint,0)+ISNULL(@acrdSrv,0)) AS ACC_CHARGE
         FROM     
        (SELECT (CASE
                    WHEN  tran_date >= @Start_Date THEN
                        CASE Is_Share_TXN 
                            WHEN '0' THEN
                                CASE Is_Debit 
                                    WHEN '1' THEN 0
                                    ELSE AMOUNT END
                            ELSE 0 END
                    ELSE 0 END) AS Deposite,
               (CASE
                    WHEN  tran_date >= @Start_Date THEN
                        CASE Is_Share_TXN 
                            WHEN '0' THEN
                                CASE Is_Debit 
                                    WHEN '1' THEN
                                        CASE T_TYPE 
                                            WHEN '1' THEN AMOUNT
                                            WHEN '3' THEN AMOUNT
                                            WHEN 'T' THEN AMOUNT
                                    ELSE 0 END
                                ELSE 0 END
                           ELSE 0 END
                    ELSE 0 END) AS WDRAW,
                (CASE
                    WHEN  tran_date >= @Start_Date THEN
                        CASE Is_Share_TXN 
                            WHEN '0' THEN
                                CASE Is_Debit 
                                    WHEN '1' THEN
                                        CASE T_TYPE 
                                            WHEN '1' THEN 0
                                            WHEN '3' THEN 0
                                            WHEN 'T' THEN 0                             
                                    ELSE AMOUNT END                     
                                ELSE 0 END
                           ELSE 0 END
                    ELSE 0 END) AS CHARGES,  
                (CASE Is_Share_TXN 
                    WHEN '1' THEN
                        CASE Is_Debit 
                                WHEN '1' THEN -AMOUNT                           
                        ELSE AMOUNT END
                    When '0' THEN 
                        CASE Is_Debit 
                                WHEN '1' THEN -AMOUNT                           
                        ELSE AMOUNT END
                    END) AS DEBCRED,Commission   
            FROM View_All_Transaction 
            WHERE tran_date <= @End_Date
              AND Client_Bp_id = @BP_ID ) AS A) AS B
FETCH NEXT FROM All_Client_Bp_Id
    INTO @BP_ID

END
CLOSE All_Client_Bp_Id
DEALLOCATE All_Client_Bp_Id
4

1 回答 1

1

嘿,我查看了您的脚本并发现..您可以通过排除DISTINCT子句来提高脚本性能,并针对 ORDER BY CLAUSE 之后的列创建非集群索引。这 2 点肯定会帮助您提高性能。

如果您有任何疑问,请告诉我。

于 2012-08-13T10:37:09.050 回答