Nemusíte používat OUTER JOIN
kromě kontroly kolik řádků bude resp. nebude být smazán.
Příklad takového dotazu viz níže (používám vygenerovaná testovací data poskytnutá na konci odpovědi)
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
S vaší velikostí dat byste měli použít HASH JOIN
s full table scan
na obou stolech, abyste dosáhli přijatelného výkonu.
V zásadě existují dvě možnosti, jak provést DELETE
Aktualizovatelné zobrazení připojení
Pamatujte, že v tomto případě vaše malá tabulka musí mít zapnutý jedinečný index ID, VERSION
(nebo primární klíč)
create unique index delta_idx on delta(id,version);
Naopak tabulka BIG by neměla mít takové omezení . To je důležité, protože to jasně ukazuje, že vaše VELKÁ tabulka je jedinou tabulkou uchování klíčů v zobrazení spojení.
Jednoduché vložení spojení do malé tabulky nemůže duplikovat řádky z velkého stolu kvůli jedinečnému omezení
Viz zde další informace o aktualizaci spojení zobrazení
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
výše odstraní řádky z BIG
tabulka, protože se jedná o jedinou tabulku uchování klíčů (viz diskuse výše)
Tento DML vede k HASH JOIN
Smazat pomocí EXISTS
Pokud vaše malá tabulka nemá primární klíč (tj. může obsahovat duplicitní řádky se stejným ID and VERSION
), musíte záložní řešení k řešení navrženému v jiné odpovědi
.
DELETE FROM big
WHERE EXISTS (SELECT null
FROM delta
WHERE delta.id = big.id and delta.version = big.version
)
Nejsou vyžadovány žádné indexy a měli byste očekávat plán provádění s HASH JOIN RIGHT SEMI
, což znamená, že oba přístupy se ve skutečnosti neliší.
Ukázková data pro test
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);