¿Es la eliminación en cascada en una tabla más eficiente que las instrucciones de eliminación individuales (ejecutadas en un solo bloque plsql)?Oracle cascade delete
Respuesta
Lo que cascade delete
hace es emitir sentencias de eliminación individuales.
Examine el siguiente caso de prueba:
create table parent
(parent_id number,
parent_name varchar2(30),
constraint parent_pk primary key (parent_id) using index);
create table child
(child_id number,
parent_id number,
child_name varchar2(30),
constraint child_pk primary key (parent_id, child_id) using index,
constraint child_fk01 foreign key (parent_id)
references parent (parent_id)
on delete cascade;
);
insert into parent
(parent_id, parent_name)
select object_id, object_name from dba_objects where rownum <= 10000;
begin
for i in 1..10
loop
insert into child
(child_id, parent_id, child_name)
select i, parent_id, parent_name
from parent;
end loop;
end;
/
exec dbms_stats.gather_table_stats (tabname => 'PARENT', cascade => true);
exec dbms_stats.gather_table_stats (tabname => 'CHILD', cascade => true);
exec dbms_monitor.session_trace_enable;
alter table child drop constraint child_fk01;
alter table child add constraint child_fk01 foreign key (parent_id)
references parent (parent_id) on delete cascade enable novalidate ;
delete from parent;
rollback;
En el archivo de seguimiento, se encuentra una línea como esta:
delete from "<MY_SCHEMA_NAME>"."CHILD" where "PARENT_ID" = :1
END OF STMT
PARSE #6:c=0,e=182,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1293353992514766
EXEC#6:c=0,e=545,p=0,cr=2,cu=32,mis=1,r=10,dep=1,og=4,tim=1293353992515354
EXEC#6:c=0,e=233,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992515644
EXEC#6:c=0,e=238,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992515931
EXEC#6:c=0,e=252,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992516229
EXEC#6:c=0,e=231,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992516507
EXEC#6:c=0,e=227,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992516782
EXEC#6:c=0,e=244,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992517072
EXEC#6:c=0,e=219,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517337
EXEC#6:c=0,e=236,p=0,cr=3,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517622
EXEC#6:c=0,e=235,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992517921
EXEC#6:c=0,e=229,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992518196
EXEC#6:c=0,e=246,p=0,cr=2,cu=32,mis=0,r=10,dep=1,og=4,tim=1293353992518487
EXEC#6:c=0,e=234,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992518767
EXEC#6:c=6999,e=570,p=0,cr=2,cu=30,mis=0,r=10,dep=1,og=4,tim=1293353992519383
Eso es Oracle emitir una instrucción de eliminación contra CHILD
para cada registro es eliminando en PARENT
.
Una cuestión diferente sería cuál de los dos es más eficiente:
DELETE FROM CHILD WHERE PARENT_ID = 1;
DELETE FROM PARENT WHERE PARENT_ID = 1;
vs
DELETE FROM PARENT WHERE PARENT_ID = 1;
ambos con on delete cascade
habilitado. Sorprendentemente, en el primer caso anterior, Oracle buscará el índice de clave foránea en la tabla secundaria para ver si existen filas que requieran una cascada. Si no existen filas, Oracle no ejecuta la eliminación en cascada.
No se pueden comparar las dos opciones de este modo. no es un problema de rendimiento, sino más diseño y estructura.
Si diseña su base de datos utilizando claves primarias/externas, será más fácil eliminarla mediante la eliminación en cascada que buscar manualmente dónde tiene claves externas en qué columna y tabla y generar sentencias SQL de mecanizado.
La principal ventaja de la función en cascada-borra es que le permite reducir la cantidad de sentencias SQL que necesita para llevar a cabo acciones de eliminación
Si desea eliminar en cascada y no tiene una clave externa definida , puede usar algo como esto:
DELETE FROM my_table
WHERE ROWID IN
(SELECT ROWID
FROM my_table
START WITH (condition_on_the_row_that_you_want_to_delete)
CONNECT BY PRIOR (primary_key) = (self_foreign_key)
)
La desventaja de una solución de este tipo sería que cualquier fila insertada que no se vea en la sesión que ejecuta la eliminación seguirá insertándose y quedando huérfana, ya que ha matado al elemento primario, pero las filas secundarias aún se insertan. –
- 1. Hibernate Delete Cascade
- 2. Dilema: Cascade delete or Join delete
- 3. CASCADE DELETE una sola vez
- 4. ¿Se ejecuta CASCADE Delete como transacción?
- 5. ¿Cómo edito una tabla para habilitar CASCADE DELETE?
- 6. Cómo usar delete cascade en MySQL MyISAM storage engine?
- 7. Django Cascade Delete en las teclas externas inversas
- 8. Entity Framework - Cascade Delete no se establece en Entity Model
- 9. Cascade Delete, misma tabla, Entity Framework 4 Code First
- 10. ¿Cómo hacer que ON DELETE CASCADE funcione en sqlite 3.7.4?
- 11. Solución de particionamiento de Oracle para DELETE problema de rendimiento
- 12. mapeo nhibernate: una colección con cascade = "all-delete-huérfano" ya no se hace referencia
- 13. MS SQL "ON DELETE CASCADE" ¿teclas externas múltiples que apuntan a la misma tabla?
- 14. Hibernate caché de segundo nivel y ON DELETE CASCADE en el esquema de base de datos
- 15. Actualizando una restricción de clave externa con ON DELETE CASCADE no actualizando?
- 16. Mapeo de NHibernate sin agregar la opción ON DELETE CASCADE a la referencia de clave externa
- 17. Nhibernate - mapeo uno a uno con Cascade all-delete-huérfano, sin eliminar el huérfano
- 18. NHibernate, "On Delete Cascade", elimina en cascada las filas en tablas relacionadas?
- 19. Cuándo utilizar "ON UPDATE CASCADE"
- 20. VEZ de disparadores y Cascade caminos
- 21. Doctrine 2 ManyToMany cascade
- 22. NHibernate Cascade = guardar-actualización "
- 23. Cómo crear una clave externa con "ON UPDATE CASCADE" en Oracle?
- 24. PostgreSQL 'Deferrable Delete' aún golpea la restricción en Delete
- 25. ¿Cómo se asegura primero que Cascade Delete esté habilitado en una relación de tabla en EF Code?
- 26. Una colección con cascade = "all-delete-huérfano" ya no fue referenciada por la instancia de la entidad propietaria
- 27. Doctrine 2 multinivel OneToOne Cascade
- 28. NHibernate Definitive Cascade application guide
- 29. Django - Cascade supresión en ManyToManyRelation
- 30. ¿Cuál es la diferencia entre DELETE_ORPHAN y DELETE?
+ 1 excelente explicación Adam –
Entonces, ¿dónde está la respuesta? que es mas eficiente – magulla
@magulla: como con la mayoría de las cosas en Oracle, depende. Puede ser más eficiente eliminar manualmente muchas filas secundarias antes de hacer la eliminación, pero nada impide que otra sesión inserte más hijos mientras está sucediendo. Teniendo en cuenta que Oracle emite una eliminación para cada fila primaria eliminada si existen hijos, si el rendimiento es primordial, haga lo posible para eliminar las filas de interés de la tabla hija con una única declaración sería una regla práctica, pero el rendimiento "mejor" no está garantizado. . –