Как я могу оптимизировать представление оракула SQL - PullRequest
0 голосов
/ 20 ноября 2019

Я не силен в SQL и Oracle, и мне нужна помощь для оптимизации этого представления, чтобы получить результат как можно быстрее. В настоящее время это занимает 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;

Как я могу оптимизировать его, чтобы сократить время выполнения?

я был бы признателен за любую помощь:)

вот план объяснения запроса

enter image description here

Ответы [ 2 ]

1 голос
/ 21 ноября 2019

Как уже упоминалось в других комментариях, ваш первый шаг - получить план выполнения запроса и найти там узкие места.

Однако я сразу вижу несколько красных флажков. Вот один из них.

Вы запускаете коррелированные агрегирующие подзапросы для каждой отдельной строки 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 строк.

Вам не нужно делать это.

Один из способов решения этой проблемы - предварительная агрегация всех соответствующих значений DATECHARGEMENT и DATENSF ONCE, изатем присоедините набор результатов к 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

Попробуйте.

0 голосов
/ 21 ноября 2019

Вы можете попробовать это, но это длинный запрос, я не знаю, сделал ли я где-то ошибку

Запрос:

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;
...