U hoeft OUTER JOIN
niet te gebruiken behalve de controle hoeveel rijen resp. zal niet worden verwijderd.
Een voorbeeld van zo'n vraag zie hieronder (ik gebruik gegenereerde testgegevens aan het einde van het antwoord)
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
Met uw gegevensgrootte moet u een HASH JOIN
. gebruiken met full table scan
op beide tafels om acceptabele prestaties te krijgen.
Er zijn in principe twee opties om de DELETE
. te doen
Bijwerkbare deelnameweergave
Merk op dat in dit geval uw kleine tabel een unieke index moet hebben op ID, VERSION
(of een primaire sleutel)
create unique index delta_idx on delta(id,version);
In tegenstelling tot de BIG-tabel zou een dergelijke beperking niet moeten hebben . Dit is belangrijk, omdat het duidelijk aangeeft dat uw GROTE tabel de enige tabel is die de sleutel behoudt in de weergave Samenvoegen.
Plaats eenvoudig een join in de kleine tabel kan geen rijen dupliceren van de grote tafel vanwege de unieke beperking
Zie hier meer informatie over Het bijwerken van een deelnameweergave
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
)
De delete
hierboven verwijdert rijen uit de BIG
tabel omdat dit de enige tabel is die de sleutel behoudt (zie de discussie hierboven)
Deze DML leidt tot een HASH JOIN
Verwijderen met EXISTS
Als uw kleine tabel geen primaire sleutel heeft (d.w.z. hij kan dubbele rijen bevatten met dezelfde ID and VERSION
) je moet terugval naar de oplossing voorgesteld in ander antwoord
.
DELETE FROM big
WHERE EXISTS (SELECT null
FROM delta
WHERE delta.id = big.id and delta.version = big.version
)
Er zijn geen indexen vereist en u mag een uitvoeringsplan verwachten met HASH JOIN RIGHT SEMI
, wat betekent dat beide benaderingen niet echt verschillend zijn.
Voorbeeldgegevens voor 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);