Non è necessario utilizzare OUTER JOIN
fatta eccezione per il controllo di quante righe risp. non essere cancellato.
Un esempio di tale query vedi sotto (uso i dati di test generati forniti alla fine della risposta)
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
Con la dimensione dei tuoi dati dovresti usare un HASH JOIN
con full table scan
su entrambi i tavoli per ottenere prestazioni accettabili.
Ci sono fondamentalmente due opzioni su come eseguire DELETE
Vista di partecipazione aggiornabile
Nota che in questo caso la tua piccola tabella deve avere un indice univoco su ID, VERSION
(o una chiave primaria)
create unique index delta_idx on delta(id,version);
Al contrario, la tabella BIG non dovrebbe avere tale vincolo . Questo è importante, perché indica chiaramente che la tua tabella BIG è l'unica tabella di conservazione delle chiavi nella vista di unione.
Metti semplicemente un join nella piccola tabella impossibile duplicare le righe dal grande tavolo per il vincolo unico
Vedi qui ulteriori informazioni sull'aggiornamento di un join Views
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
)
Il delete
sopra rimuove le righe da BIG
tabella perché questa è l'unica tabella di conservazione delle chiavi (vedi la discussione sopra)
Questo DML porta a un HASH JOIN
Elimina con EXISTS
Se la tua piccola tabella non ha una chiave primaria (cioè può contenere righe duplicate con lo stesso ID and VERSION
) devi fallback alla soluzione proposta in altra risposta
.
DELETE FROM big
WHERE EXISTS (SELECT null
FROM delta
WHERE delta.id = big.id and delta.version = big.version
)
Non sono richiesti indici e dovresti aspettarti un piano di esecuzione con HASH JOIN RIGHT SEMI
, il che significa che entrambi gli approcci non sono molto diversi.
Dati di esempio per il 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);