1

我在下面编写了一个 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
4

1 回答 1

0

只是为了好玩 - 看看如果你在 INSERT、UPDATE、SELECT 语句中删除每一次出现的 ORDER 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 的输出与此组合语句进行比较来测试其准确性。

于 2012-05-24T15:24:02.380 回答