sql >> Database teknologi >  >> RDS >> Oracle

Sletning af poster fra en tabel sammenføjet med en anden tabel SQL

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);


  1. Kortlæg et PostGIS-geometripunktfelt med Hibernate on Spring Boot

  2. pg client.query() venter ikke på afventningen

  3. Problem med forespørgselsdata i en tabel

  4. Python Twisted og databaseforbindelser