Неправильное преобразование Left Join с использованием гетерогенной службы Oracle
У меня есть база данных Oracle, подключенная с помощью связи с удаленной БД. Моя удаленная БД не имеет ничего общего с ВНЕШНИМИ СОЕДИНЕНИЯМИ, поэтому Гетерогенная служба преобразует мой запрос в несколько простых запросов и объединяет результаты.
Например у меня есть 3 таблицы:
create table join_email
(
EMAIL_ID FLOAT(10)
SENDER VARCHAR2(128)
)
INSERT INTO join_email VALUES (1,'bmdrrfh@gmail.com')
INSERT INTO join_email VALUES (2,'n3qcd@gmail.com')
create table join_email_receivers
(
EMAIL_ID FLOAT(10)
RECEIVER VARCHAR2(128)
)
INSERT INTO join_email_receivers VALUES (1,'9wtcptyzn@yahoo.com')
INSERT INTO join_email_receivers VALUES (1,'8w7o5@yahoo.com')
INSERT INTO join_email_receivers VALUES (1,'jlwtc@yahoo.com')
INSERT INTO join_email_receivers VALUES (2,'fpm@yandex.ru')
INSERT INTO join_email_receivers VALUES (2,'a@mail.com')
create table join_email_cc
(
EMAIL_ID FLOAT(10)
CC VARCHAR2(128)
)
INSERT INTO join_email_cc VALUES (1,'rg1yzjc@mail.com')
Я хочу запросить строки из таблицы 1 и слева соединить строки со 2-го и 3-го по email_id. Мой запрос выглядит так:
select em.sender, emr.receiver, emcc.cc
from join_email@DG4 em
LEFT JOIN join_EMAIL_RECEIVERS@DG4 emr on emr.email_id=em.email_id
LEFT JOIN join_EMAIL_CC@DG4 emcc on emcc.email_id=em.email_id
where em.sender = 'bmdrrfh@gmail.com' and emr.receiver = '9wtcptyzn@yahoo.com';
Проблема заключается в том, что гетерогенная служба преобразует этот запрос в два следующих запроса:
<SELECT A2."EMAIL_ID",A2."SENDER",A1."RECEIVER" FROM "JOIN_EMAIL" A2,"JOIN_EMAIL_RECEIVERS" A1 WHERE A1."EMAIL_ID"=A2."EMAIL_ID" AND A2."SENDER"='bmdrrfh@gmail.com' AND A1."RECEIVER"='9wtcptyzn@yahoo.com'>
а также
<SELECT "CC","EMAIL_ID" FROM "JOIN_EMAIL_CC">
2-й запрос - это неверный запрос FULL SCAN, он должен быть предложением WHERE для email_id.
У меня вопрос, как сказать Гетерогенному Сервису, как преобразовать мой запрос в правильном порядке?
1 ответ
Первый LEFT OUTER JOIN
на самом деле INNER JOIN
из-за предиката равенства на столбце emr.receiver
, поэтому он правильно преобразован Oracle.
Если СУБД, работающая на удаленном сайте, изначально поддерживает внешние объединения, вы можете создать представление на удаленном сайте, исключив WHERE
пункт, например
На удаленном сайте (DG4
в вашем примере):
create view my_view as
select em.sender, emr.receiver, emcc.cc
from join_email em
LEFT JOIN join_EMAIL_RECEIVERS emr on emr.email_id=em.email_id
LEFT JOIN join_EMAIL_CC emcc on emcc.email_id=em.email_id
А потом на местном сайте:
select *
from my_view@DG4
where em.sender = 'bmdrrfh@gmail.com'
and emr.receiver = '9wtcptyzn@yahoo.com'