sql >> Databáze >  >> RDS >> Oracle

Mazání záznamů z jedné tabulky připojené k jiné tabulce SQL

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


  1. Jak sečíst vícenásobný počet z více tabulek

  2. Použití MySQL Galera Cluster Replication k vytvoření geograficky distribuovaného clusteru:Část druhá

  3. Smazat všechny cizí klíče v databázi (MySql)

  4. Dokáže Laravel zvládnout aplikace s vysokou návštěvností?