3

Oracle 10g データベースに対する SQL クエリのパフォーマンスを改善しようとしています。次の2つのクエリがあります。

クエリ 1

SELECT DISTINCT 
    WMS_EVENT_LOG.LOG_ID,
    WMS_EVENT_LOG.EVENT_ARG4,
    WMS_EVENT_LOG.EVENT_TYPE,
    WMS_EVENT_LOG.EVENT_ARG1,
    WMS_EVENT_LOG.EVENT_ARG3,
    WMS_EVENT_LOG.PROD_ITEM_ID,
    TRUNC(WMS_EVENT_LOG.LOG_DATE) AS LOG_DATE,
    WMS_EVENT_LOG.PALLET_ID,
    WMS_EVENT_LOG.LOG_USER,
    WMS_EVENT_LOG.POSTED_TO_KCAT,
    POSTEDWMSTRANS.POSTTRAN,
    DECODE(POSTEDWMSTRANS.POSTTRAN, 'Y', POSTEDWMSTRANS.CMNT, WMS_EVENT_LOG.EVENT_ARG3) AS CMNT --cmnt = comment
FROM 
    VMR_WMSEVENTLOG WMS_EVENT_LOG, 
    VM_ADJUST_REASON ADJUST_REASON,
    ( 
      SELECT 
          INVENTORY.BOM_TYPE AS POSTTRAN,
          INVENTORY.PROD_ITEM_ID,
          INVENTORY.CMNT,
          INVENTORY.WMSLINK
      FROM 
          VR_BOM INVENTORY
      WHERE 
          INVENTORY.BOM_TDATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') - 15 AND 
          INVENTORY.BOM_TDATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') + 15 AND
          INVENTORY.WMSLINK IS NOT NULL AND 
          INVENTORY.BOM_TYPE <> 'HLD' 
    ) POSTEDWMSTRANS
WHERE 
    WMS_EVENT_LOG.LOG_DATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.LOG_DATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.EVENT_TYPE = 31 AND
    ADJUST_REASON.ADJUST_REASON_CODE NOT IN ('SPL') AND
    ADJUST_REASON.ADJUST_REASON_CODE = WMS_EVENT_LOG.EVENT_ARG1 AND ( 
        WMS_EVENT_LOG.EVENT_ARG1 <> 'MOV' AND 
        WMS_EVENT_LOG.EVENT_ARG2 = 'ADJUST' 
    ) AND 
    WMS_EVENT_LOG.PROD_ITEM_ID = POSTEDWMSTRANS.PROD_ITEM_ID(+) AND
    WMS_EVENT_LOG.EVENT_ARG4 = POSTEDWMSTRANS.WMSLINK(+)  

クエリ 2

--VARIABLE report_start_date VARCHAR
--VARIABLE report_end_date VARCHAR

SELECT DISTINCT 
    WMS_EVENT_LOG.LOG_ID,
    WMS_EVENT_LOG.EVENT_ARG4,
    WMS_EVENT_LOG.EVENT_TYPE,
    WMS_EVENT_LOG.EVENT_ARG1,
    WMS_EVENT_LOG.EVENT_ARG3,
    WMS_EVENT_LOG.PROD_ITEM_ID,
    TRUNC(WMS_EVENT_LOG.LOG_DATE) AS LOG_DATE,
    WMS_EVENT_LOG.PALLET_ID,
    WMS_EVENT_LOG.LOG_USER,
    WMS_EVENT_LOG.POSTED_TO_KCAT,
    POSTEDWMSTRANS.POSTTRAN,
    DECODE(POSTEDWMSTRANS.POSTTRAN, 'Y', POSTEDWMSTRANS.CMNT, WMS_EVENT_LOG.EVENT_ARG3) AS CMNT --cmnt = comment
FROM 
    VMR_WMSEVENTLOG WMS_EVENT_LOG, 
    VM_ADJUST_REASON ADJUST_REASON,
    ( 
      SELECT 
          INVENTORY.BOM_TYPE AS POSTTRAN,
          INVENTORY.PROD_ITEM_ID,
          INVENTORY.CMNT,
          INVENTORY.WMSLINK
      FROM 
          VR_BOM INVENTORY
      WHERE 
          INVENTORY.BOM_TDATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') - 15 AND 
          INVENTORY.BOM_TDATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') + 15 AND
          INVENTORY.WMSLINK IS NOT NULL AND 
          INVENTORY.BOM_TYPE <> 'HLD' 
    ) POSTEDWMSTRANS
WHERE 
    WMS_EVENT_LOG.LOG_DATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.LOG_DATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.EVENT_TYPE = 31 AND
    ADJUST_REASON.ADJUST_REASON_CODE NOT IN ('SPL') AND
    ADJUST_REASON.ADJUST_REASON_CODE = WMS_EVENT_LOG.EVENT_ARG1 AND ( 
        WMS_EVENT_LOG.EVENT_ARG1 <> 'MOV' AND 
        WMS_EVENT_LOG.EVENT_ARG2 = 'ADJUST' 
    ) AND 
    WMS_EVENT_LOG.PROD_ITEM_ID = POSTEDWMSTRANS.PROD_ITEM_ID(+) AND
    WMS_EVENT_LOG.EVENT_ARG4 = POSTEDWMSTRANS.WMSLINK(+)

ご覧のとおり、2 つのクエリの唯一の違いは、上部のコメントです。

query 2PL/SQL 開発者で複数回実行すると、何らかの理由で 1 秒以内に完了します。同じ環境で複数回実行query 1すると、完了するまでに 15 秒かかります。

返された行を確認しましたが、どちらも同じデータで同じ数の行を返します。

クエリ 2 がより速く終了するのはなぜですか?
PL/SQL Developer の設定が誤った情報を提供している可能性があると思います。


これはすべて 8i 用に書かれたもので、10g 用に改良しています。

4

1 に答える 1

3

最初のクエリは共有プールにあります (コメントで引用されている既存のレガシー手順に対応しています)。最初のクエリは、共有プールからコンパイルされたプランを使用するため、更新時間が短縮されますが、両方のクエリの説明プランは同じです (説明プランが異なるのはなぜですか)。

于 2014-07-23T19:30:45.243 に答える