Du behøver ikke bruge OUTER JOIN
bortset fra kontrollen hvor mange rækker der vil hhv. vil ikke slettes.
Et eksempel på en sådan forespørgsel se nedenfor (jeg bruger genererede testdata leveret i slutningen af svaret)
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
Med din datastørrelse skal du bruge en HASH JOIN
med full table scan
på begge borde for at få acceptabel ydeevne.
Der er dybest set to muligheder, hvordan man gør DELETE
Opdaterbar deltagelsesvisning
Bemærk, at din lille tabel i dette tilfælde skal have et unikt indeks på ID, VERSION
(eller en primær nøgle)
create unique index delta_idx on delta(id,version);
I modsætning hertil burde BIG-tabellen ikke have en sådan begrænsning . Dette er vigtigt, fordi det tydeligt indikerer, at din BIG-tabel er den eneste nøglebevarende tabel i sammenføjningsvisningen.
Sæt enkelt en join til den lille tabel kan ikke duplikere rækker fra det store bord på grund af den unikke kontraint
Se her flere oplysninger om opdatering af en deltagelsesvisning
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
ovenfor fjerner rækker fra BIG
tabel, fordi dette er den eneste nøglebevarende tabel (se diskussionen ovenfor)
Denne DML fører til en HASH JOIN
Slet med EXISTS
Hvis din lille tabel ikke har nogen primær nøgle (dvs. den kan indeholde duplikerede rækker med samme ID and VERSION
) skal du tilbagegang til løsningen foreslået i andet svar
.
DELETE FROM big
WHERE EXISTS (SELECT null
FROM delta
WHERE delta.id = big.id and delta.version = big.version
)
Der kræves ingen indekser, og du bør forvente en eksekveringsplan med HASH JOIN RIGHT SEMI
, hvilket betyder, at begge tilgange ikke er virkelig forskellige.
Eksempeldata til 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);