SQL IN语句需要永远加载

时间:2013-01-03 09:24:15

标签: sql tsql

有谁知道为什么以下SQL语句需要永远加载???

select LE_ACNT_STKG.ID_PRD_RP
from       
    TR_LTM_PHY_CNT  
    inner join AS_ITM_STK   ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                            and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner join LE_ACNT_STKG ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT  
                            and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner JOIN AS_ITM       ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
    inner join LO_LCN       ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
    INNER JOIN DO_CNT_PHY   on  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
    INNER JOIN CO_EV        on (DO_CNT_PHY.ID_STR_RT         = CO_EV.ID_STR_RT  
                            and DO_CNT_PHY.ID_EV         = CO_EV.ID_EV)                                     
where   
    LE_ACNT_STKG.ID_PRD_RP >= 4792
    AND LE_ACNT_STKG.ID_PRD_RP <= 6693
    AND LE_ACNT_STKG.ID_PRD_RP IN (
                    SELECT TOP 1 LE_ACNT_STKG.ID_PRD_RP 
                    FROM LE_ACNT_STKG 
                    INNER JOIN CA_PRD_RP ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
                    WHERE 
                        CA_PRD_RP.TY_PRD_RP = 'CD' AND
                        LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND
                        LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND
                        (
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
                           OR --If we're in the latest period, which is still open
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
                           OR --if there isn't one for the current period, get the previous one
                          (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
                        )
                    ORDER BY
                        LE_ACNT_STKG.ID_PRD_RP DESC)

我相信这是因为IN()子查询。当我拿出那个声明时,它加载的速度要快得多。如果是这样的话,我该怎么办呢?我尝试用IN替换EXISTS,但返回的结果完全不同。

5 个答案:

答案 0 :(得分:0)

将子查询的结果转储到临时表中,然后将该临时表连接到主查询。

SELECT
    LE_ACNT_STKG.ID_PRD_RP
INTO
    #MyFirstTempTable
FROM
    LE_ACNT_STKG 
INNER JOIN
    CA_PRD_RP
    ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
WHERE 
    CA_PRD_RP.TY_PRD_RP = 'CD' AND
    LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND
    LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND
    (
        (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
        OR --If we're in the latest period, which is still open
        (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
        OR --if there isn't one for the current period, get the previous one
        (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
     )

答案 1 :(得分:0)

我认为你可以简单地使用像这样的查询组:

select distinct SUB.ID_PRD_RP from (
  select CA_PRD_RP.ID_PRD_RP,MAX(LE_ACNT_STKG.ID_PRD_RP) AS ID_PRD_RP
  from       
      TR_LTM_PHY_CNT  
      inner join AS_ITM_STK   ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                  and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
      inner join LE_ACNT_STKG ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT  
                  and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
      inner JOIN AS_ITM       ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
      inner join LO_LCN       ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
      INNER JOIN DO_CNT_PHY   on  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
      INNER JOIN CO_EV        on (DO_CNT_PHY.ID_STR_RT = CO_EV.ID_STR_RT  
                  and DO_CNT_PHY.ID_EV = CO_EV.ID_EV)                                     
      INNER JOIN CA_PRD_RP ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
  where   
      LE_ACNT_STKG.ID_PRD_RP >= 4792
      AND LE_ACNT_STKG.ID_PRD_RP <= 6693
      AND CA_PRD_RP.TY_PRD_RP = 'CD'
      AND (
      (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
        OR --If we're in the latest period, which is still open
      (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
          OR --if there isn't one for the current period, get the previous one
      (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
    )
  GROUP BY
    CA_PRD_RP.ID_PRD_RP) SUB

答案 2 :(得分:0)

cipet huat这样做,

select LE_ACNT_STKG.ID_PRD_RP
from       
    TR_LTM_PHY_CNT  
    inner join AS_ITM_STK   ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                            and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner join LE_ACNT_STKG ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT  
                            and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
    inner JOIN AS_ITM       ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
    inner join LO_LCN       ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
    INNER JOIN DO_CNT_PHY   on  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
    INNER JOIN CO_EV        on (DO_CNT_PHY.ID_STR_RT         = CO_EV.ID_STR_RT  
                            and DO_CNT_PHY.ID_EV         = CO_EV.ID_EV)                                     
    inner join 
                    SELECT TOP 1 LE_ACNT_STKG.ID_PRD_RP 
                    FROM LE_ACNT_STKG 
                    INNER JOIN CA_PRD_RP ON (LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)
                    WHERE 
                        CA_PRD_RP.TY_PRD_RP = 'CD' AND
                        LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND
                        LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND
                        (
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  >= CO_EV.TS_EV_ACT_EF) 
                           OR --If we're in the latest period, which is still open
                          (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END  IS NULL) 
                           OR --if there isn't one for the current period, get the previous one
                          (CA_PRD_RP.TS_PRD_RP_END < CO_EV.TS_EV_ACT_EF)
                        )
                    ORDER BY
                        LE_ACNT_STKG.ID_PRD_RP DESC) temp
   on temp.ID_PRD_RP = LE_ACNT_STKG.ID_PRD_RP
where   
    LE_ACNT_STKG.ID_PRD_RP >= 4792
    AND LE_ACNT_STKG.ID_PRD_RP <= 6693

答案 3 :(得分:0)

如果没有DDL这很难测试很好的悲伤,表名很糟糕^^ 这可能是朝着正确方向迈出的一步,但很难确定!

;WITH CTE0 AS
(
    SELECT   ID_PRD_RP  = TR.ID_STR_RT
            ,TR.ID_ITM
            ,ID_PRD_RP  = MAX(LE.ID_PRD_RP) 
    FROM LE_ACNT_STKG   LE 
    JOIN CA_PRD_RP      CA  ON LE.ID_PRD_RP = CA.ID_PRD_RP
    JOIN TR_LTM_PHY_CNT TR  ON TR.ID_STR_RT = LE.ID_STR_RT AND LE.ID_ITM = TR.ID_ITM
    JOIN DO_CNT_PHY     DO  ON  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO.ID_DCM_PHY_CNT
    JOIN CO_EV          CO  ON (DO.ID_STR_RT = CO.ID_STR_RT and DO.ID_EV = CO.ID_EV)
    WHERE CA_PRD_RP.TY_PRD_RP = 'CD' 
    AND (
            (CA.TS_PRD_RP_STRT <= CO.TS_EV_ACT_EF AND CA.TS_PRD_RP_END  >= CO.TS_EV_ACT_EF) 
            OR --If we're in the latest period, which is still open
            (CA.TS_PRD_RP_STRT <= CO.TS_EV_ACT_EF AND CA.TS_PRD_RP_END  IS NULL) 
            OR --if there isn't one for the current period, get the previous one
            (CA.TS_PRD_RP_END < CO.TS_EV_ACT_EF)
        )
    GROUP BY TR.ID_STR_RT, TR.ID_ITM
)
SELECT LE_ACNT_STKG.ID_PRD_RP
FROM TR_LTM_PHY_CNT  
JOIN AS_ITM_STK     ON (AS_ITM_STK.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT
                            and AS_ITM_STK.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
join LE_ACNT_STKG   ON (LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT and LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM)  
JOIN AS_ITM         ON (AS_ITM.ID_ITM = AS_ITM_STK.ID_ITM and AS_ITM.ID_STR_RT = AS_ITM_STK.ID_STR_RT)  
join LO_LCN         ON (LE_ACNT_STKG.ID_LCN = LO_LCN.ID_LCN) 
JOIN DO_CNT_PHY     ON  TR_LTM_PHY_CNT.ID_DCM_PHY_CNT = DO_CNT_PHY.ID_DCM_PHY_CNT  
JOIN CO_EV          ON (DO_CNT_PHY.ID_STR_RT         = CO_EV.ID_STR_RT and DO_CNT_PHY.ID_EV = CO_EV.ID_EV)   
JOIN CTE0   CTE ON CTE.ID_PRD_RP =    LE_ACNT_STKG.ID_PRD_RP                               
WHERE LE_ACNT_STKG.ID_PRD_RP >= 4792
AND LE_ACNT_STKG.ID_PRD_RP <= 6693

答案 4 :(得分:-1)

内连接(                     SELECT TOP 1 LE_ACNT_STKG.ID_PRD_RP                     来自LE_ACNT_STKG                     INNER JOIN CA_PRD_RP ON(LE_ACNT_STKG.ID_PRD_RP = CA_PRD_RP.ID_PRD_RP)                     哪里                         CA_PRD_RP.TY_PRD_RP ='CD'AND                         LE_ACNT_STKG.ID_STR_RT = TR_LTM_PHY_CNT.ID_STR_RT AND                         LE_ACNT_STKG.ID_ITM = TR_LTM_PHY_CNT.ID_ITM AND                         (                           (CA_PRD_RP.TS_PRD_RP_STRT&lt; = CO_EV.TS_EV_ACT_EF和CA_PRD_RP.TS_PRD_RP_END&gt; = CO_EV.TS_EV_ACT_EF)                            或者 - 如果我们处于最新阶段,那仍然是开放的                           (CA_PRD_RP.TS_PRD_RP_STRT&lt; = CO_EV.TS_EV_ACT_EF和CA_PRD_RP.TS_PRD_RP_END为空)                            或者 - 如果当前期间没有一个,则获取前一个                           (CA_PRD_RP.TS_PRD_RP_END&lt; CO_EV.TS_EV_ACT_EF)                         )                     订购                         LE_ACNT_STKG.ID_PRD_RP DESC))temp    on temp.ID_PRD_RP = LE_ACNT_STKG.ID_PRD_RP