提高子查询的性能

Improve Performance of Subquery

目前我有一个子查询,它本身有一个子查询。就性能而言,当我将其放入我的存储过程时,这不会很好。我想知道是否有任何方法可以提高这段代码的性能,或者看看不同的写法?

基本上我是在查找价格数据,但如果价格发生变化,我们只会将价格记录加载到我们的仓库中。所以我需要查找我们收到价格的每个工具的最新日期,然后 return 该价格。我有以下代码:

DECLARE @EndDate    DATETIME

SET @EndDate = '2015-10-31'

SELECT                  
ip2.INSTR_ID
,   ip2.PRC_TMS
,   ip2.PRC_CURR_CDE
,   COALESCE(MAX(CASE 
                    WHEN ip2.PRC_TYP = 'CLO' THEN ip2.PRC_QUOTE_AMT 
                END),
        MAX(ip2.PRC_QUOTE_AMT)) AS PRC_QUOTE_AMT

FROM ISSUE_PRICE AS ip2

INNER JOIN (
            SELECT 
                INSTR_ID AS INSTR_ID
            ,   MAX(PRC_TMS) AS PRC_TMS

            FROM ISSUE_PRICE
            WHERE PRC_SRCE_TYP = 'SSC'
            AND PRC_TMS <= @EndDate
            AND PRC_TYP IN ('LST', 'CLO')
            GROUP BY INSTR_ID) AS i2
ON i2.INSTR_ID = ip2.INSTR_ID
AND i2.PRC_TMS = ip2.PRC_TMS

WHERE ip2.PRC_SRCE_TYP = 'SSC'
AND ip2.PRC_TYP IN ('LST', 'CLO')
GROUP BY ip2.PRC_TMS, ip2.INSTR_ID, ip2.PRC_CURR_CDE

任何帮助将不胜感激。

谢谢

这可以通过使用 Row_Number window 函数来识别每个 INSTR_ID 的最大值 PRC_TMS 来实现。试试这个,

;WITH cte
     AS (SELECT Row_number()OVER(partition BY INSTR_ID
                    ORDER BY PRC_TMS DESC) AS rn,*
         FROM   ISSUE_PRICE
         WHERE  PRC_SRCE_TYP = 'SSC'
                AND PRC_TMS <= @EndDate
                AND PRC_TYP IN ( 'LST', 'CLO' ))
SELECT ip2.INSTR_ID,
       ip2.PRC_TMS,
       ip2.PRC_CURR_CDE,
       COALESCE(Max(CASE
                      WHEN ip2.PRC_TYP = 'CLO' THEN ip2.PRC_QUOTE_AMT
                    END), Max(ip2.PRC_QUOTE_AMT)) AS PRC_QUOTE_AMT
FROM   cte
WHERE  RN = 1
GROUP  BY ip2.PRC_TMS,
          ip2.INSTR_ID,
          ip2.PRC_CURR_CDE 

子查询不一定会导致性能问题。但是,您可以使用 window 函数更高效、更简洁地完成您想要的操作:

SELECT ip.INSTR_ID, ip.PRC_TMS, ip.PRC_CURR_CDE,
       COALESCE(MAX(CASE WHEN ip.PRC_TYP = 'CLO' THEN ip.PRC_QUOTE_AMT 
                    END),
                MAX(ip.PRC_QUOTE_AMT)
               ) AS PRC_QUOTE_AMT    
FROM (SELECT ip.*,
             MAX(PRC_TMC) OVER (PARTITION BY INSTR_ID) as MAX_PRC_TMS
      FROM ISSUE_PRICE ip
      WHERE ip.PRC_SRCE_TYP = 'SSC' AND ip.PRC_TYP IN ('LST', 'CLO')
     ) ip
WHERE ip.PRC_TMS = ip.MAX_PRC_TMS
GROUP BY ip.PRC_TMS, ip.INSTR_ID, ip.PRC_CURR_CDE;