Вам не нужно использовать OUTER JOIN
за исключением проверки, сколько строк будет соотв. не будет удалено.
Пример такого запроса см. ниже (я использую сгенерированные тестовые данные, предоставленные в конце ответа)
with del as (
select delta.id, delta.version,
decode(big.id,null,0,1) is_deleted
from delta
left outer join big
on delta.id = big.id and delta.version = big.version
)
select is_deleted, count(*) cnt, max(id||'.'||version) eg_id_vers
from del
group by is_deleted;
IS_DELETED CNT EG_ID_VERS
---------- ---------- ----------
1 20000 99995.0
0 20 100100.0
С вашими данными Размер, который вы должны использовать HASH JOIN
с full table scan
для обеих таблиц, чтобы получить приемлемую производительность.
Существует два основных способа сделать DELETE
Обновляемый вид соединения.
Обратите внимание, что в этом случае ваша маленькая таблица должна иметь уникальный индекс на ID, VERSION
(или первичный ключ)
create unique index delta_idx on delta(id,version);
Наоборот БОЛЬШОЙ таблица не должна иметь такого ограничения . Это важно, потому что ясно показывает, что ваша БОЛЬШАЯ таблица является единственной таблицей сохранения ключа в представлении соединения.
Просто поместите соединение в небольшой стол не может дублировать строки из большой таблицы из-за уникального ограничения
См. здесь дополнительная информация о Обновление представлений объединения
delete from
(
select delta.id, delta.version, big.id big_id, big.version
from big
join delta
on delta.id = big.id and delta.version = big.version
)
Приведенное выше delete
удаляет строки из таблицы BIG
, поскольку это единственная таблица , сохраняющая ключи (см. Обсуждение выше)
Этот DML приводит к HASH JOIN
Удалить с помощью EXISTS
Если в вашем маленьком столе нет первичный ключ (т. е. он может содержать повторяющиеся строки с одинаковыми ID and VERSION
), вы должны отступить к решению, предложенному в другой ответ .
DELETE FROM big
WHERE EXISTS (SELECT null
FROM delta
WHERE delta.id = big.id and delta.version = big.version
)
Нет индексов требуется, и вы должны ожидать план выполнения с HASH JOIN RIGHT SEMI
, что означает, что оба подхода не отличаются друг от друга.
Пример данных для теста
create table big as
select
trunc(rownum/10) id, mod(rownum,10) version,
lpad('x',10,'Y') pad
from dual connect by level <= 1000000;
/* the DELTA table has 50 times less rows,
allow some rows out of range of the BIG table - those rows will not be deleted **/
drop table delta;
create table delta as
select
trunc(rownum*50/10) id, mod(rownum*50,10) version
from dual connect by level <= 1001000/50;
create unique index delta_idx on delta(id,version);