English 中文(简体)
如何加快SQL脚本的更新速度
原标题:How can i speed up the update on a SQL Script

我在下面写了一个SQL脚本,但运行速度有问题。在“使用销售数据更新购买情况”一节之前,一切都很好。更新@Results表需要很长时间。有什么办法可以加快速度吗?

USE [IV7]
GO
/*-------------------------------------------------------------------------------------    -----------------
Declare all variables
---------------------------------------------------------------------------------------    ---------------*/
DECLARE @StartDateTime  DATETIME
DECLARE @EndDateTime    DATETIME
DECLARE @l_Section      VARCHAR(100)
DECLARE @Debug          CHAR(1)

DECLARE @Worktable  TABLE
(
    PortfolioID     VARCHAR(20)
,   SettlementDate  DATETIME
,   ContractDate    DATETIME
,   BrokerCode      VARCHAR(100)
,   [Broker]        VARCHAR(100)
,   Currency        CHAR(3)
,   TransCode       CHAR(3)
,   TransactionType CHAR(3)
,   Nominal         DECIMAL(22,3)
,   ForwardRate     DECIMAL(22,8)
,   SpotRate        DECIMAl(22,8)
,   DealID          VARCHAR(20)     -- ThinkFolio ID
,   TranID          VARCHAR(20)      
,   TranType        CHAR(3)
,   RKSTranID       VARCHAR(16)     -- This is the RKS transaction number.  It is unique per transaction in RKS, but multi-leg transactions will have same value, allowing us to link them together (e.g. FX s, etc)
,   USDSPOTRate     FLOAT
,   BuyNominalUSD   DECIMAL(22,3)
)

DECLARE @Results    TABLE
(
    PortfolioID     VARCHAR(20)
,   SettlementDate  DATETIME
,   ContractDate    DATETIME
,   BrokerCode      VARCHAR(100)
,   [Broker]        VARCHAR(100)
,   BuyCurrency     CHAR(3)
,   BuyNominal      DECIMAL(22,3)
,   SellCurrency    CHAR(3)
,   SellNominal     DECIMAL(22,3)
,   MarketValue     DECIMAL(22,3)
,   ForwardRate     DECIMAL(22,8)
,   SpotRate        DECIMAL(22,8)
,   DealID          VARCHAR(20)     
,   RKSTranID       VARCHAR(16)         -- Not used for final output
,   BuyNominalUSD   DECIMAL(22,3)       
)

DECLARE @FX TABLE 
(   
    RateDate        DATETIME
,   BaseCCY         CHAR(3)
,   RateCCY         CHAR(3)
,   MDInd           CHAR(1)
,   Rate            FLOAT
,   RateType        VARCHAR(10)     
)
/*--------------------------------------------------------------------------------------------------------------------------------
Set default values
--------------------------------------------------------------------------------------------------------------------------------*/
SET @l_Section =  Setting Default Values 
SET @StartDateTime =  2011-04-01 00:00:00.000 
SET @EndDateTime =  2012-03-31 23:59:59.000 
SET @Debug =  Y 

IF @Debug =  Y 
BEGIN
    SELECT @l_Section
    SELECT @StartDateTime AS StartDate, @EndDateTime AS EndDate
END
/*--------------------------------------------------------------------------------------------------------------------------------
Insert into FX
--------------------------------------------------------------------------------------------------------------------------------*/  
INSERT INTO @FX 
SELECT * FROM fn_Generic_FXRates ( 2011-04-01 , 2012-03-31 , D , SPOT , USD , 999 )
/*--------------------------------------------------------------------------------------------------------------------------------
Insert values into @WorkTable
--------------------------------------------------------------------------------------------------------------------------------*/
SET @l_Section =  Insert values into @WorkTable 

BEGIN
INSERT INTO @WorkTable
SELECT 
    t.acct_id                                   AS PortfolioID
,   t.cntrct_pay_tms                            AS SettlementDate
,   t.trd_ex_eff_tms                            AS ContractDate
,   t.trd_brkr_mnem                             AS BrokerCode
,   t.trd_brkr_nme                              AS Broker
,   t.local_curr_cde                            AS Currency
,   t.trn_cl_cde                                AS TransCode
,   t.trn_cde                                   AS TransactionType
,   t.quantity                                  AS Nominal
,   CASE
        WHEN t.trn_cde IN (  FFB , FFS ) THEN 
        t.fld4_rte  ELSE NULL
    END                                         AS ForwardRate
,   CASE
        WHEN t.trn_cde IN (  FSB , FSS ) THEN 
        t.fld4_rte  ELSE NULL
    END                                         AS Spot
,   t.exec_trd_id                               AS DealID
,   t.actg_trn_id                               AS TranID
,   t.trn_cde                                   AS TranType
,   t.deal_id                                   AS RKSTranID
,   fx.rate                                     AS USDSPOTRate
,   CASE
        WHEN t.trn_cde IN ( FFB , FSB ) THEN t.quantity * fx.rate
        ELSE 0
    END                                         AS BuyNominalUSD

FROM tranevent_dg AS t

INNER JOIN issue_dg AS i
     ON i.instr_id = t.instr_id
    AND i.iss_typ =  FFX 

INNER JOIN @FX AS fx
            ON fx.RateCCY = t.local_curr_cde
            AND fx.RateDate = t.trd_ex_eff_tms

WHERE t.exec_trd_id IS NULL
  AND t.inq_basis_num = 1
  AND t.trd_ex_eff_tms BETWEEN @StartDateTime AND @EndDateTime

ORDER BY t.deal_id

END

IF @Debug =  Y 
BEGIN
    SELECT @l_Section
    SELECT * FROM @WorkTable
    ORDER BY RKSTranID 
END
/*--------------------------------------------------------------------------------------------------------------------------------
Insert Buy values into @Results
--------------------------------------------------------------------------------------------------------------------------------*/
SET @l_Section =  Insert Buy values into @Results 

BEGIN
INSERT INTO @Results
SELECT 
    w.PortfolioID       AS PortfolioID
,   CONVERT(VARCHAR(10),w.SettlementDate,112)   AS SettlementDate
,   CONVERT(VARCHAR(10),w.ContractDate,112)     AS ContractDate
,   w.BrokerCode        AS BrokerCode
,   w.Broker            AS Broker
,   w.Currency          AS BuyCurrency
,   w.Nominal           AS BuyNominal
,   NULL                AS SellCurrency
,   NULL                AS SellNominal
,   NULL                AS MarketValue
,   w.ForwardRate       AS ForwardRate
,   w.SpotRate          AS SpotRate
,   w.DealID            AS DealID
,   w.RKSTranID         AS RKSTranID
,   w.BuyNominalUSD     AS BuyNominalUSD

FROM @WorkTable AS w
WHERE w.TranType IN ( FFB , FSB )
ORDER BY w.RKSTranID

END

IF @Debug =  Y 
BEGIN
    SELECT @l_Section
    SELECT * FROM @Results
    ORDER BY RKSTranID
END

/*--------------------------------------------------------------------------------------------------------------------------------
Update Buys with sales data
--------------------------------------------------------------------------------------------------------------------------------*/  
SET @l_Section =  Update Buys with sales data 

BEGIN
UPDATE @Results
SET
    SellCurrency = wtSell.Currency
,   SellNominal = wtSell.Nominal

FROM @Results AS r

LEFT OUTER JOIN @WorkTable AS wtSell
 ON wtSell.PortfolioID = r.PortfolioID
AND wtSell.RKSTranID = r.RKSTranID
AND wtSell.TranType IN ( FFS , FSS )

END

IF @Debug =  Y 
BEGIN
    SELECT @l_Section
    SELECT * FROM @Results
    ORDER BY RKSTranID
END
/*--------------------------------------------------------------------------------------------------------------------------------
Final Select
--------------------------------------------------------------------------------------------------------------------------------*/  
SET @l_Section =  Final Output Select 

SELECT  
PortfolioID     AS [Portfolio ID]
,   SettlementDate  AS [Settlement Date]
,   ContractDate    AS [Contract Date]
,   BrokerCode      AS [BrokerCode]
,   Broker          AS [Broker]
,   BuyCurrency     AS [Buy Ccy]
,   BuyNominal      AS [Buy Nominal]
,   BuyNominalUSD   AS [Buy Nominal USD]
,   SellCurrency    AS [Sell Ccy]
,   SellNominal     AS [Sell Nominal]
,   MarketValue     AS [Market Value]
,   ForwardRate     AS [Forward Rate]
,   SpotRate        AS [Spot Rate]
,   DealID          As [Deal ID]

 FROM @Results

ORDER BY DealID
问题回答

只是为了好玩——看看如果你删除INSERT、UPDATE、SELECT语句中或DER BY子句的每次出现会发生什么。

正如所评论的那样,您应该真正尝试释放表变量,并使用添加了适当索引的适当(临时)表。

这个怎么样?我基本上将你所有的SQL组合成一个。显然,我无法测试它的准确性,但也许这会给你一些想法。你比我们更了解你的表和数据,也许你可以酌情删除不必要的SQL。

SELECT 
    w.PortfolioID       AS PortfolioID
    ,   CONVERT(VARCHAR(10),w.SettlementDate,112)   AS SettlementDate
    ,   CONVERT(VARCHAR(10),w.ContractDate,112)     AS ContractDate
    ,   w.BrokerCode        AS BrokerCode
    ,   w.Broker            AS Broker
    ,   w.Currency          AS BuyCurrency
    ,   w.Nominal           AS BuyNominal
    ,   wtSell.Currency     AS SellCurrency -- wtSell 
    ,   wtSell.Nominal      AS SellNominal -- wtSell
    ,   NULL                AS MarketValue
    ,   w.ForwardRate       AS ForwardRate
    ,   w.SpotRate          AS SpotRate
    ,   w.DealID            AS DealID
    ,   w.RKSTranID         AS RKSTranID
    ,   w.BuyNominalUSD     AS BuyNominalUSD
FROM 
(
    SELECT 
        t.acct_id                                   AS PortfolioID
        ,   t.cntrct_pay_tms                            AS SettlementDate
        ,   t.trd_ex_eff_tms                            AS ContractDate
        ,   t.trd_brkr_mnem                             AS BrokerCode
        ,   t.trd_brkr_nme                              AS Broker
        ,   t.local_curr_cde                            AS Currency
        ,   t.trn_cl_cde                                AS TransCode
        ,   t.trn_cde                                   AS TransactionType
        ,   t.quantity                                  AS Nominal
        ,   CASE WHEN t.trn_cde IN ( FFB , FFS ) THEN t.fld4_rte ELSE NULL END AS ForwardRate
        ,   CASE WHEN t.trn_cde IN ( FSB , FSS ) THEN t.fld4_rte ELSE NULL END AS Spot
        ,   t.exec_trd_id                               AS DealID
        ,   t.actg_trn_id                               AS TranID
        ,   t.trn_cde                                   AS TranType
        ,   t.deal_id                                   AS RKSTranID
        ,   fx.rate                                     AS USDSPOTRate
        ,   CASE WHEN t.trn_cde IN ( FFB , FSB ) THEN t.quantity * fx.rate ELSE 0 END AS BuyNominalUSD
    FROM 
        tranevent_dg AS t
    INNER JOIN 
        issue_dg AS i ON i.instr_id = t.instr_id AND i.iss_typ =  FFX 
    INNER JOIN 
        @FX AS fx ON fx.RateCCY = t.local_curr_cde AND fx.RateDate = t.trd_ex_eff_tms
    WHERE 
        t.exec_trd_id IS NULL
    AND 
        t.inq_basis_num = 1
    AND 
        t.trd_ex_eff_tms BETWEEN @StartDateTime AND @EndDateTime
) AS w
LEFT JOIN
(
    SELECT 
        t.acct_id                                   AS PortfolioID
        ,   t.cntrct_pay_tms                            AS SettlementDate
        ,   t.trd_ex_eff_tms                            AS ContractDate
        ,   t.trd_brkr_mnem                             AS BrokerCode
        ,   t.trd_brkr_nme                              AS Broker
        ,   t.local_curr_cde                            AS Currency
        ,   t.trn_cl_cde                                AS TransCode
        ,   t.trn_cde                                   AS TransactionType
        ,   t.quantity                                  AS Nominal
        ,   CASE WHEN t.trn_cde IN ( FFB , FFS ) THEN t.fld4_rte ELSE NULL END AS ForwardRate
        ,   CASE WHEN t.trn_cde IN ( FSB , FSS ) THEN t.fld4_rte ELSE NULL END AS Spot
        ,   t.exec_trd_id                               AS DealID
        ,   t.actg_trn_id                               AS TranID
        ,   t.trn_cde                                   AS TranType
        ,   t.deal_id                                   AS RKSTranID
        ,   fx.rate                                     AS USDSPOTRate
        ,   CASE WHEN t.trn_cde IN ( FFB , FSB ) THEN t.quantity * fx.rate ELSE 0 END AS BuyNominalUSD
    FROM 
        tranevent_dg AS t
    INNER JOIN 
        issue_dg AS i ON i.instr_id = t.instr_id AND i.iss_typ =  FFX 
    INNER JOIN 
        @FX AS fx ON fx.RateCCY = t.local_curr_cde AND fx.RateDate = t.trd_ex_eff_tms
    WHERE 
        t.exec_trd_id IS NULL
    AND 
        t.inq_basis_num = 1
    AND 
        t.trd_ex_eff_tms BETWEEN @StartDateTime AND @EndDateTime
) wtSell ON wtSell.PortfolioID = r.PortfolioID AND wtSell.RKSTranID = r.RKSTranID AND wtSell.TranType IN ( FFS , FSS )
WHERE 
    w.TranType IN ( FFB , FSB )
order by 
    w.DealID

您可以通过简单地将SQL的输出与此组合语句进行比较来测试其准确性。





相关问题
Update a table with records from another table

I am trying to update my table 1 with some field value from table 2 based on a condition. But am unable to get the proper query. Here s the condition: I have a table 1 with date field which should be ...

MySql - Way to update portion of a string?

I m looking for a way to update just a portion of a string via MySQL query. For example, if I have 10 records all containing string as part of the field value, is there a way to change string to ...

Using comma with an update sentence

I want to update a row which has some html tags inside. For instance: src= /imagem.png ></ p></ body> > UPDATE ISTANBUL_TABLE SET TEXT = < > body>< p>< img ...

SQL Update from a Select

I want to update two fields of table (Store) from a select of others tables, but i don´t know how i can do it. The SQL system is in AS/400, so doesn´t have SQL Server or Oracle tricks :( Here is the ...

How to MYSQL UPDATE fieldINT!=‘4’ doesn’t work [closed]

Im trying to UPDATE queueStatusINT WHERE statusINT is 8 and queueStatusINT is NOT equal to 2 and type is $type. But I keep getting an error: ERROR 1064 (42000) at line 1: You have an error in your ...

Python MySQLdb: Update if exists, else insert

I am looking for a simple way to query an update or insert based on if the row exists in the first place. I am trying to use Python s MySQLdb right now. This is how I execute my query: self.cursor....

SQL Trigger 1 row at a time

I m creating an update trigger that goes like this (SQL Server 2005): Is the state column of the row is 23 or 25 don t update it. Else update it. It s very simple. I m trying OldState = (Select ...

热门标签