No necesita usar OUTER JOIN
excepto por el control de cuántas filas habrá resp. no ser eliminado.
Vea un ejemplo de dicha consulta a continuación (utilizo los datos de prueba generados que se proporcionan al final de la respuesta)
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 el tamaño de sus datos, debe usar un HASH JOIN
con full table scan
en ambas tablas para obtener un rendimiento aceptable.
Básicamente, hay dos opciones para hacer DELETE
Vista de unión actualizable
Tenga en cuenta que, en este caso, su tabla pequeña debe tener un índice único ID, VERSION
(o una clave principal)
create unique index delta_idx on delta(id,version);
Al contrario, la mesa GRANDE no debería tener tal restricción . Esto es importante, porque indica claramente que su GRAN mesa es la única mesa que preserva las claves en la vista de unión.
Simplemente coloque una combinación en la tabla pequeña no se pueden duplicar filas de la mesa grande debido a la contraste único
Consulte aquí más información sobre Actualización de vistas de unión
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
)
El delete
arriba elimina filas del BIG
porque esta es la única tabla que conserva claves (ver la discusión anterior)
Este DML conduce a un HASH JOIN
Eliminar con EXISTE
Si su tabla pequeña no tiene clave principal (es decir, puede contener filas duplicadas con el mismo ID and VERSION
) debe retroceder a la solución propuesta en otra respuesta
.
DELETE FROM big
WHERE EXISTS (SELECT null
FROM delta
WHERE delta.id = big.id and delta.version = big.version
)
No se requieren índices y debe esperar un plan de ejecución con HASH JOIN RIGHT SEMI
, lo que significa que ambos enfoques no son realmente diferentes.
Datos de muestra para la prueba
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);