2

次の 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たが、返される結果がまったく異なります。

4

5 に答える 5

0

次のようなクエリでgroupbyを使用できると思います。

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
于 2013-01-03T10:19:41.247 に答える
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)
     )
于 2013-01-03T09:35:20.993 に答える
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
于 2013-01-03T10:42:58.073 に答える
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
于 2013-01-03T10:27:55.917 に答える
-1

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 -- まだ開いている最新の期間にいる場合 (CA_PRD_RP.TS_PRD_RP_STRT <= CO_EV.TS_EV_ACT_EF AND CA_PRD_RP.TS_PRD_RP_END IS NULL) ) OR -- 存在しない場合'現在の期間の t は、前のものを取得します (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

于 2013-01-03T10:38:14.017 に答える