Vous n'avez pas besoin d'utiliser OUTER JOIN
à l'exception de la vérification du nombre de lignes resp. ne va pas être supprimé.
Un exemple d'une telle requête voir ci-dessous (j'utilise les données de test générées fournies à la fin de la réponse)
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
Avec la taille de vos données, vous devez utiliser un HASH JOIN
avec full table scan
sur les deux tables pour obtenir des performances acceptables.
Il existe essentiellement deux options pour effectuer le DELETE
Vue de jointure pouvant être mise à jour
Notez que dans ce cas votre petite table doit avoir un index unique sur ID, VERSION
(ou une clé primaire)
create unique index delta_idx on delta(id,version);
Au contraire, la table BIG ne devrait pas avoir une telle contrainte . Ceci est important, car cela indique clairement que votre table BIG est la seule table de préservation des clés dans la vue de jointure.
Simple mettre une jointure à la petite table ne peut pas dupliquer les lignes de la grande table en raison de la contrainte unique
Voir ici plus d'informations sur la mise à jour d'une vue de jointure
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
)
Le delete
ci-dessus supprime les lignes du BIG
car c'est la seule table de conservation des clés (voir la discussion ci-dessus)
Ce DML conduit à un HASH JOIN
Supprimer avec EXISTS
Si votre petite table n'a pas de clé primaire (c'est-à-dire qu'elle peut contenir des lignes dupliquées avec les mêmes ID and VERSION
) vous devez replier à la solution proposée dans autre réponse
.
DELETE FROM big
WHERE EXISTS (SELECT null
FROM delta
WHERE delta.id = big.id and delta.version = big.version
)
Aucun index n'est requis et vous devez vous attendre à un plan d'exécution avec HASH JOIN RIGHT SEMI
, ce qui signifie que les deux approches ne sont pas vraiment différentes.
Exemple de données pour le 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);