2016-05-23 64 views
0

我真的很感谢您在调整下面的SQL查询方面的帮助。当我取消它时,它持续运行了10分钟。在Oracle中优化SQL查询

MARC_SEL给了我31253条记录52秒 和MVKE_SEL给我的431060条记录22秒

我重构它条款,但没有太多的使用changed.What别的我可以加入,使其更快。请帮忙。

WITH ALL_XSAP_MATNR 
    AS (SELECT DISTINCT XSAP.MATNR,XSAP.MTART,XSAP.SOURCE FROM XXX_MAIN.XXX_XSAP XSAP 
     WHERE SOURCE = 'SP') 
    , MARC_SEL AS 
    (SELECT DISTINCT A.SOURCE 
        ,MARA.MATNR 
        ,MARA.MTART  
        ,MARA.MBRSH 
        ,MARC.WERKS  
        ,NVL(PX.WERKS,'/') DWERK 
        ,NVL(MBEW.HKMAT,'/') HKMAT 
        ,NVL(MBEW.EKALR,'/') EKALR 
        ,NVL(MARC.STAWN,'/')  STAWN 
    FROM ALL_XSAP_MATNR A 
      , XXX_MAIN.XXX_SAP_MARA MARA 
      , XXX_MAIN.XXX_SAP_MARC MARC 
      , XXX_MAIN.XXX_MP_WERKS_PLANT_XREF PX 
      , XXX_MAIN.XXX_SAP_MBEW MBEW 
    WHERE A.MATNR = MARA.MATNR 
     AND A.MTART = MARA.MTART 
     AND MARA.MATNR = MARC.MATNR 
     AND MARC.MATNR = MBEW.MATNR 
     AND MARC.WERKS = MBEW.BWKEY 
     AND PX.LEGACY_PLANT = MARC.WERKS 
     AND PX.SOURCE = 'SP'         
    ) 
    , MVKE_SEL AS 
    ( SELECT DISTINCT 
        MVKE.MATNR 
        ,'/' LEGACY_ORG  
        ,'/' LEGACY_MATNR  
        ,NVL(MX_VKORG.SAP_DE_VAL,'/') VKORG   
        ,NVL(SUBSTR(MX_VKORG.SAP_DE,6,2),'/') VTWEG 
      --  ,NVL(TVRKME.MSEH3,'/') VRKME   
        ,NVL(MVKE.KONDM,'/') KONDM   
       ,NVL(MVKE.VERSG,'/') VERSG 
        ,'/' IPRKZ   
        ,'/' MHDRZ,NVL(MVKE.VMSTA,'/')  VMSTA 
        ,NVL(TO_CHAR(MVKE.VMSTD ,'YYYYMMDD'),'/') VMSTD  
        ,NVL(MVKE.PMATN,'/') PMATN   
        ,NVL(MVKE.MVGR2,'/')  MVGR2  
        ,NVL(MVKE.MVGR3,'/')  MVGR3   
        ,NVL(MVKE.VAVME,'/')  VAVME   
        ,'/' MVGR4   
        ,'/' MVGR5   
        ,NVL(MVKE.MTPOS,'/') MTPOS   
        ,NVL(MVKE.PRAT1,'/') PRAT1   
        ,NVL(MVKE.SKTOF,'/') SKTOF   
        ,'/' AUMNG   
        ,NVL(MVKE.PRODH,'/') PRODH  
        ,'/' MVGR1    
        ,NVL(MVKE.KTGRM,'/') KTGRM 
        ,MX_VKORG.DESC4 
    FROM  XXX_MAIN.XXX_SAP_MVKE MVKE 
      , XXX_MAIN.XXX_MP_VKVT_XREF MX_VKORG  
    WHERE MX_VKORG.SOURCE_DE_VAL = MVKE.VKORG 
     AND SUBSTR(MX_VKORG.SAP_DE,6,2) = MVKE.VTWEG 
     AND MX_VKORG.SOURCE_TBL = 'SP' 
     AND MX_VKORG.SOURCE_DE = 'MVKE' 
     AND SUBSTR(MX_VKORG.SAP_DE,1,5)= 'VKORG' 
     AND MX_VKORG.DESC2 IS NULL ) 
    SELECT DISTINCT 
         MARC.SOURCE 
         ,MARC.MATNR 
         ,MARC.MTART  
         ,MARC.MBRSH 
         ,MARC.WERKS  
         ,MARC.DWERK 
         ,MARC.HKMAT 
         ,MARC.EKALR 
         ,MARC.STAWN 
         ,MVKE.LEGACY_ORG 
         ,MVKE.LEGACY_MATNR 
         ,MVKE.VKORG 
         ,MVKE.VTWEG 
         ,MVKE.KONDM 
         ,MVKE.VERSG 
         ,MVKE.VMSTA 
         ,MVKE.VMSTD 
         ,MVKE.PMATN 
         ,MVKE.MVGR2 
         ,MVKE.MVGR3 
         ,MVKE.VAVME 
         ,MVKE.MTPOS 
         ,MVKE.PRAT1 
         ,MVKE.SKTOF 
         ,MVKE.PRODH 
         ,MVKE.KTGRM 
    FROM MARC_SEL MARC 
      , MVKE_SEL MVKE 
     WHERE MARC.MATNR = MVKE.MATNR 
     AND MARC.WERKS = MVKE.DESC4 
+2

请不要使用'WHERE'语句来加入,但使用'LEFT | RIGHT | INNER JOIN ... ON'语句。加入的WHERE语句是遗留的,不应该使用。 – Munir

+1

请编辑您的问题,并为上述表格/视图添加“CREATE TABLE”和/或“CREATE VIEW”。包括定义的索引。查询还包括EXPLAIN PLAN的输出。谢谢。 –

回答

0

添加提示到子查询,它回来了一分钟。

WITH ALL_XSAP_MATNR 
AS (SELECT /*+ materialize */ DISTINCT XSAP.MATNR,XSAP.MTART,XSAP.SOURCE FROM XXX_MAIN.XXX_XSAP XSAP 
    WHERE SOURCE = 'SP') 
, MARC_SEL AS 
(SELECT /*+ materialize */ DISTINCT A.SOURCE 
       ,MARA.MATNR 
       ,MARA.MTART  
       ,MARA.MBRSH 
       ,MARC.WERKS  
       ,NVL(PX.WERKS,'/') DWERK 
       ,NVL(MBEW.HKMAT,'/') HKMAT 
       ,NVL(MBEW.EKALR,'/') EKALR 
       ,NVL(MARC.STAWN,'/')  STAWN 
FROM ALL_XSAP_MATNR A 
     , XXX_MAIN.XXX_SAP_MARA MARA 
     , XXX_MAIN.XXX_SAP_MARC MARC 
     , XXX_MAIN.XXX_MP_WERKS_PLANT_XREF PX 
     , XXX_MAIN.XXX_SAP_MBEW MBEW 
WHERE A.MATNR = MARA.MATNR 
    AND A.MTART = MARA.MTART 
    AND MARA.MATNR = MARC.MATNR 
    AND MARC.MATNR = MBEW.MATNR 
    AND MARC.WERKS = MBEW.BWKEY 
    AND PX.LEGACY_PLANT = MARC.WERKS 
    AND PX.SOURCE = 'SP'         
) 
, MVKE_SEL AS 
( SELECT /*+ materialize */ DISTINCT 
       MVKE.MATNR 
       ,'/' LEGACY_ORG  
       ,'/' LEGACY_MATNR  
       ,NVL(MX_VKORG.SAP_DE_VAL,'/') VKORG   
       ,NVL(SUBSTR(MX_VKORG.SAP_DE,6,2),'/') VTWEG 
     --  ,NVL(TVRKME.MSEH3,'/') VRKME   
       ,NVL(MVKE.KONDM,'/') KONDM   
      ,NVL(MVKE.VERSG,'/') VERSG 
       ,'/' IPRKZ   
       ,'/' MHDRZ,NVL(MVKE.VMSTA,'/')  VMSTA 
       ,NVL(TO_CHAR(MVKE.VMSTD ,'YYYYMMDD'),'/') VMSTD  
       ,NVL(MVKE.PMATN,'/') PMATN   
       ,NVL(MVKE.MVGR2,'/')  MVGR2  
       ,NVL(MVKE.MVGR3,'/')  MVGR3   
       ,NVL(MVKE.VAVME,'/')  VAVME   
       ,'/' MVGR4   
       ,'/' MVGR5   
       ,NVL(MVKE.MTPOS,'/') MTPOS   
       ,NVL(MVKE.PRAT1,'/') PRAT1   
       ,NVL(MVKE.SKTOF,'/') SKTOF   
       ,'/' AUMNG   
       ,NVL(MVKE.PRODH,'/') PRODH  
       ,'/' MVGR1    
       ,NVL(MVKE.KTGRM,'/') KTGRM 
       ,MX_VKORG.DESC4 
FROM  XXX_MAIN.XXX_SAP_MVKE MVKE 
     , XXX_MAIN.XXX_MP_VKVT_XREF MX_VKORG  
WHERE MX_VKORG.SOURCE_DE_VAL = MVKE.VKORG 
    AND SUBSTR(MX_VKORG.SAP_DE,6,2) = MVKE.VTWEG 
    AND MX_VKORG.SOURCE_TBL = 'SP' 
    AND MX_VKORG.SOURCE_DE = 'MVKE' 
    AND SUBSTR(MX_VKORG.SAP_DE,1,5)= 'VKORG' 
    AND MX_VKORG.DESC2 IS NULL ) 
SELECT DISTINCT /*+ use_hash(MARC,MVKE) */ 
        MARC.SOURCE 
        ,MARC.MATNR 
        ,MARC.MTART  
        ,MARC.MBRSH 
        ,MARC.WERKS  
        ,MARC.DWERK 
        ,MARC.HKMAT 
        ,MARC.EKALR 
        ,MARC.STAWN 
        ,MVKE.LEGACY_ORG 
        ,MVKE.LEGACY_MATNR 
        ,MVKE.VKORG 
        ,MVKE.VTWEG 
        ,MVKE.KONDM 
        ,MVKE.VERSG 
        ,MVKE.VMSTA 
        ,MVKE.VMSTD 
        ,MVKE.PMATN 
        ,MVKE.MVGR2 
        ,MVKE.MVGR3 
        ,MVKE.VAVME 
        ,MVKE.MTPOS 
        ,MVKE.PRAT1 
        ,MVKE.SKTOF 
        ,MVKE.PRODH 
        ,MVKE.KTGRM 
FROM MARC_SEL MARC 
     , MVKE_SEL MVKE 
    WHERE MARC.MATNR = MVKE.MATNR 
    AND MARC.WERKS = MVKE.DESC4 
2

开始简化你的查询,你不需要做多DISTINCT秒(这是只需要在最后输出),你选择,你是不是输出多列。你也加入了一些你没有选择的表格,如果这些表格有多个匹配的行,那么它可能会产生重复的行 - 使用类似EXISTS的东西可以消除这些连接。

像这样:

WITH MARC_SEL AS (
    SELECT A.SOURCE, 
     MARA.MATNR, 
     MARC.WERKS 
    FROM XXX_MAIN.XXX_XSAP A 
     INNER JOIN XXX_MAIN.XXX_SAP_MARA MARA 
     ON ( A.MATNR = MARA.MATNR 
      AND A.MTART = MARA.MTART) 
     INNER JOIN XXX_MAIN.XXX_SAP_MARC MARC 
     ON ( MARA.MATNR = MARC.MATNR) 
    WHERE EXISTS(SELECT 'X' 
       FROM XXX_MAIN.XXX_MP_WERKS_PLANT_XREF PX 
       WHERE PX.LEGACY_PLANT = MARC.WERKS 
       AND PX.SOURCE = 'SP') 
    AND EXISTS(SELECT 'X' 
       FROM XXX_MAIN.XXX_SAP_MBEW MBEW 
       WHERE MARC.MATNR = MBEW.MATNR 
       AND MARC.WERKS = MBEW.BWKEY) 
    AND A.SOURCE = 'SP' 
) 
, MVKE_SEL AS (
    SELECT NVL(MX_VKORG.SAP_DE_VAL,'/') VKORG, 
      NVL(SUBSTR(MX_VKORG.SAP_DE,6,2),'/') VTWEG, 
      MX_VKORG.DESC4 
    FROM XXX_MAIN.XXX_MP_VKVT_XREF MX_VKORG 
    WHERE EXISTS (SELECT 'X' 
        FROM XXX_MAIN.XXX_SAP_MVKE MVKE 
        WHERE MX_VKORG.SOURCE_DE_VAL = MVKE.VKORG 
        AND SUBSTR(MX_VKORG.SAP_DE,6,2) = MVKE.VTWEG) 
    AND  MX_VKORG.SOURCE_TBL = 'SP' 
    AND  MX_VKORG.SOURCE_DE = 'MVKE' 
    AND  SUBSTR(MX_VKORG.SAP_DE,1,5)= 'VKORG' 
    AND  MX_VKORG.DESC2 IS NULL 
) 
SELECT DISTINCT 
     MARC.SOURCE, 
     MARC.MATNR, 
     MVKE.VKORG, 
     MARC.WERKS, 
     MVKE.VTWEG 
FROM MARC_SEL MARC 
     INNER JOIN MVKE_SEL MVKE 
     ON ( MARC.MATNR = MVKE.MATNR 
      AND MARC.WERKS = MVKE.DESC4) 
+0

道歉@ MT0,我确实需要其他表的值:我编辑了原始问题中的代码,以显示我在输出中需要的所有值。 – Tina