簡體   English   中英

我如何優化視圖 oracle sql

[英]how can i optimize view oracle sql

我在 sql 和 oracle 方面並不強,我需要幫助來優化這個視圖,以便盡快得到結果。 目前,我運行它的 select 子句需要 7 分鍾。

這是視圖:

CREATE OR REPLACE FORCE VIEW "DMUSEWADM"."SOUS_FAMILLE_WITH_CATALOG_INFO" 

("IDSOUSFAMILLE", "LIBELLESOUSFAMILLE", "DATEMODIFSF", "IDFAMILLE", 
"CHEMIN", "GNP", "TYPEFICHIER", "ESTPLANIFIABLE", "DATEPLANIFIABLE", 
"AUTEURMODIFSF", "NATURESOUSFAMILLE", "LIBELLEMETIERSOUSFAMILLE", 
"CONTACTPRODUCTEUR", "CATALOGVISIBILITY", "PREVISIONALDATE", 
"DATEDERNIERCHARGEMENT", "DATEPROCHAINCHARGEMENT", "LIBELLEFAMILLE") AS 

SELECT SF."IDSOUSFAMILLE",SF."LIBELLESOUSFAMILLE",SF."DATEMODIFSF",SF."IDFAMILLE",SF."CHEMIN",SF."GNP", SF."TYPEFICHIER",SF."ESTPLANIFIABLE",SF."DATEPLANIFIABLE",SF."AUTEURMODIFSF",SF."NATURESOUSFAMILLE",SF."LIBELLEMETIERSOUSFAMILLE",SF."CONTACTPRODUCTEUR",SF."CATALOGVISIBILITY",SF."PREVISIONALDATE", 
( SELECT datefinchrgt from chargement where numchrgt = ( select  max(numchrgt) from CHARGEMENT where nomhbase = ( select nomhbase from hbase where nomes = SF.IDSOUSFAMILLE ) and etatchrgt = 'OK')
) as DATEDERNIERCHARGEMENT, 
( SELECT (
    CASE WHEN DATECHARGEMENT IS NOT NULL THEN
        (
        CASE WHEN DATENSF IS NOT NULL THEN
            GREATEST(DATECHARGEMENT, DATENSF)
        ELSE
            DATECHARGEMENT
        END
        )
    ELSE
        DATENSF
    END
    )
  FROM 
    (
      SELECT 
        subsf.idsousfamille as subid,
        (SELECT max(c.dateauplustot) FROM CHARGEMENT c, HBASE h WHERE c.typechrgt = 'HBASEESDATA' and c.etatchrgt = 'PREVU' and c.nomhbase = h.nomhbase and h.nomes = subsf.idsousfamille) as DATECHARGEMENT,
        (SELECT max(nsf.dateauplustot) FROM NAS_SOUSFAMILLE nsf WHERE nsf.etatchrgt = 'PREVU' AND nsf.sousfamille = subsf.idsousfamille) as DATENSF
      FROM sousfamille subsf
    ) 
 WHERE subid = SF.idsousfamille
) as DATEPROCHAINCHARGEMENT,

( 
  SELECT f.libelleFamille from famille f where sf.idfamille = f.idfamille
) as LIBELLEFAMILLE

FROM SOUSFAMILLE SF;

我該如何優化它以減少執行時間?

我將不勝感激任何幫助:)

這是查詢的解釋計划

在此處輸入圖像描述

正如其他評論已經提到的那樣,您的第一步是獲取查詢執行計划,並在那里搜索瓶頸。

但是,我立即在這里看到多個危險信號。 這是其中之一。

您正在為sousfamille的每一行運行相關的聚合子查詢。

  SELECT 
    subsf.idsousfamille as subid,
    (SELECT max(c.dateauplustot) FROM CHARGEMENT c, HBASE h WHERE c.typechrgt = 'HBASEESDATA' and c.etatchrgt = 'PREVU' and c.nomhbase = h.nomhbase and h.nomes = subsf.idsousfamille) as DATECHARGEMENT,
    (SELECT max(nsf.dateauplustot) FROM NAS_SOUSFAMILLE nsf WHERE nsf.etatchrgt = 'PREVU' AND nsf.sousfamille = subsf.idsousfamille) as DATENSF
  FROM sousfamille subsf

假設您的sousfamille表有 1M 行,而NAS_SOUSFAMILLE有 1M 行,那么您總共將讀取 1G 行。

你不必這樣做。

解決此問題的一種方法是將所有相關DATECHARGEMENTDATENSF值預先聚合一次,然后將結果集加入到sousfamille中。

SELECT 
    subsf.idsousfamille as subid,
    h.DATECHARGEMENT,
    nsf.DATENSF
  FROM sousfamille subsf
  left join (SELECT h.homes, max(c.dateauplustot) DATECHARGEMENT FROM CHARGEMENT c, HBASE h WHERE c.typechrgt = 'HBASEESDATA' and c.etatchrgt = 'PREVU' and c.nomhbase = h.nomhbase) h 
  on subsf.idsousfamille = h.homes
  left join (SELECT nsf.sousfamille, max(nsf.dateauplustot) DATENSF FROM NAS_SOUSFAMILLE nsf WHERE nsf.etatchrgt = 'PREVU') nsf
  on nsf.sousfamille = subsf.idsousfamille

試試看。

你可以試試這個,但這是一個很長的查詢我不知道我是否在某個地方犯了錯誤

詢問:

SELECT SF."IDSOUSFAMILLE",
       SF."LIBELLESOUSFAMILLE",
       SF."DATEMODIFSF",
       SF."IDFAMILLE",
       SF."CHEMIN",
       SF."GNP",
       SF."TYPEFICHIER",
       SF."ESTPLANIFIABLE",
       SF."DATEPLANIFIABLE",
       SF."AUTEURMODIFSF",
       SF."NATURESOUSFAMILLE",
       SF."LIBELLEMETIERSOUSFAMILLE",
       SF."CONTACTPRODUCTEUR",
       SF."CATALOGVISIBILITY",
       SF."PREVISIONALDATE",

       d.datefinchrgt AS DATEDERNIERCHARGEMENT,

       CASE WHEN DATECHARGEMENT IS NOT NULL THEN (CASE WHEN DATENSF IS NOT NULL THEN GREATEST(DATECHARGEMENT, DATENSF)
                                                   ELSE DATECHARGEMENT END)
            ELSE DATENSF END AS DATEPROCHAINCHARGEMENT,

       f.libelleFamille AS LIBELLEFAMILLE         
FROM SOUSFAMILLE SF
LEFT JOIN famille f
    ON sf.idfamille = f.idfamille
LEFT JOIN sousfamille subsf
    ON subsf.idsousfamille = SF.idsousfamille
      LEFT JOIN (SELECT nsf.sousfamille,
                        max(nsf.dateauplustot) DATECHARGEMENT
                 FROM NAS_SOUSFAMILLE nsf
                 WHERE nsf.etatchrgt = 'PREVU'
                 GROUP BY nsf.sousfamille) nsf
              ON nsf.sousfamille = subsf.idsousfamille
      LEFT JOIN (SELECT h.nomes,
                        max(c.dateauplustot) DATENSF
                 FROM CHARGEMENT c
                 JOIN HBASE h
                   ON c.nomhbase = h.nomhbase
                   AND c.typechrgt = 'HBASEESDATA'
                   AND c.etatchrgt = 'PREVU'
                  GROUP BY  h.nomes) h
               ON h.nomes = subsf.idsousfamille
LEFT JOIN (SELECT c.datefinchrgt,
                  c.nomes
           FROM (SELECT ch.datefinchrgt,
                        hb.nomes,
                        ROW_NUMBER()OVER(PARTITION BY datefinchrgt ORDER BY ch.numchrgt desc) as rn
                 FROM hbase hb
                 JOIN CHARGEMENT ch
                   ON ch.nomhbase = hb.nomhbase
                   AND hb.etatchrgt = 'OK') c
            WHERE c.rn = 1) d
                ON d.nomes = SF.IDSOUSFAMILLE;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM