SQL: Oracle: оптимизировать запрос на внешнее соединение влево - PullRequest
0 голосов
/ 03 октября 2018

У меня есть 1 локальная таблица (все имена столбцов отличаются от удаленных таблиц, кроме одной) и 2 удаленные таблицы (с одинаковыми именами столбцов), для которых мне нужно объединить данные.

Ниже приведен запрос Iнаписал, используя LEFT OUTER JOIN и UNION, но производительность низкая.

Может ли кто-нибудь помочь оптимизировать этот запрос?

select
"CONTROL_M_SERVER",
"HOST",
CASE
WHEN "AGSTAT" = 'V' THEN 'Available'
WHEN "AGSTAT" = 'U' THEN 'Unavailable'
WHEN "AGSTAT" = 'R' THEN 'Discovering'
ELSE 'Not Defined in Control-M'
END as Agent_Status,
T1.VERSION,
"PORTS",
"MANAGEMENT_IP",
"OPERATING_SYSTEM",
"CLUSTER_ALIAS",
"NODEGROUP",
"APPLICATION_ID",
"DATE_CONFIGURED",
"CONFIGURED_BY"
from "CTMAGENTAUDIT" T1
left outer join (select NODEID,AGSTAT from CMR_NODES@SPDB UNION ALL select NODEID,AGSTAT from CMR_NODES@DEVDB) T2 on T2.NODEID = T1.HOST;

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

Я бы сделал что-то вроде этого:

select
"CONTROL_M_SERVER",
"HOST",
CASE
WHEN "AGSTAT" = 'V' THEN 'Available'
WHEN "AGSTAT" = 'U' THEN 'Unavailable'
WHEN "AGSTAT" = 'R' THEN 'Discovering'
ELSE 'Not Defined in Control-M'
END as Agent_Status,
T1.VERSION,
"PORTS",
"MANAGEMENT_IP",
"OPERATING_SYSTEM",
"CLUSTER_ALIAS",
"NODEGROUP",
"APPLICATION_ID",
"DATE_CONFIGURED",
"CONFIGURED_BY",
(select t2.NODEID, t2.AGSTAT from CMR_NODES@SPDB t2 where t1.host = t2.nodeid),  
(select t3.NODEID, t3.AGSTAT from CMR_NODES@DEVDB t3 where T1.HOST = T3.NODEID) from t1;
0 голосов
/ 03 октября 2018

Ваш запрос в основном:

select . . .
from CTMAGENTAUDIT T1 left outer join
     (select NODEID, AGSTAT
      from CMR_NODES@SPDB UNION ALL
      select NODEID, AGSTAT
      from CMR_NODES@DEVDB
     ) T2
     on T2.NODEID = T1.HOST;

Предполагая, что комбинации NODEID / AGSTAT уникальны в каждой из CMR_NODE таблиц, я бы написал это как:

select . . .,
       coalesce(s1.AGSTAT, s2.AGSTAT) as AGSTAT,
       (case coalesce(s1.AGSTAT, s2.AGSTAT) 
            when 'V' then 'Available'
            when 'U' then 'Unavailable'
            when 'R' then 'Discovering'
            else 'Not Defined in Control-M'
        end) as Agent_Status
from CTMAGENTAUDIT T1 left outer join
     CMR_NODES@SPDB s1
     on s1.NODEID = T1.HOST left outer join
     CMR_NODES@DEVDB s2
     on s1.NODEID = T1.HOST

Это, по крайней мере, позволит оптимизировать каждую таблицу отдельно - что должно помочь.

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

0 голосов
/ 03 октября 2018

Основная проблема, которую я вижу в вашем запросе, - это крайнее левое соединение между CTMAGENTAUDIT и подзапросом, содержащим объединение.Проблема с этим подзапросом заключается в том, что, как написано, Oracle не может использовать какой-либо индекс для объединения.Это означает, что Oracle, вероятно, придется прибегнуть к более медленному методу при объединении, возможно, к полному сканированию.

Один из подходов здесь состоит в том, чтобы создать материализованное представление, содержащее запрос объединения, а затем проиндексировать его:

CREATE MATERIALIZED VIEW T2 AS
SELECT NODEID, AGSTAT FROM CMR_NODES@SPDB
UNION ALL
SELECT NODEID, AGSTAT FROM CMR_NODES@DEVDB;

CREATE INDEX mv_node_idx ON T2 (NODEID);

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

SELECT
    CONTROL_M_SERVER,
    HOST,
    CASE WHEN AGSTAT = 'V' THEN 'Available'
         WHEN AGSTAT = 'U' THEN 'Unavailable'
         WHEN AGSTAT = 'R' THEN 'Discovering'
         ELSE 'Not Defined in Control-M' END AS Agent_Status,
    T1.VERSION,
    PORTS,
    MANAGEMENT_IP,
    OPERATING_SYSTEM,
    CLUSTER_ALIAS,
    NODEGROUP,
    APPLICATION_ID,
    DATE_CONFIGURED,
    CONFIGURED_BY
FROM CTMAGENTAUDIT T1
LEFT OUTER JOIN T2
    ON T2.NODEID = T1.HOST;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...