在Oracle中调优SQL查询

时间:2016-05-23 21:58:01

标签: sql oracle performance

我非常感谢您在调整以下SQL查询时提供的帮助。当我取消它时,它一直运行10分钟。

MARC_SEL在52秒内给了我31,253条记录 和MVKE_SEL在22秒内给了我431,060条记录

我重构了它以使用with子句但没有太大的改变。我可以合并什么来使它更快。请帮忙。

    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 个答案:

答案 0 :(得分: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 )

答案 1 :(得分: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