Czy usuwanie kaskadowe w tabeli jest wydajniejsze niż pojedyncze instrukcje usuwania (wykonywane w jednym bloku plsql)?Usuwanie kaskady Oracle
Odpowiedz
To, co cascade delete
robi, to wydaje indywidualne wyciągi.
zbadania następujących przypadek testowy:
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;
W pliku śledzenia, można znaleźć linię:
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
To Oracle wydawania DELETE przeciwko CHILD
dla każdego rekordu jest to usuwanie w PARENT
.
Innym zagadnieniem, które będzie z nich są bardziej skuteczne:
DELETE FROM CHILD WHERE PARENT_ID = 1;
DELETE FROM PARENT WHERE PARENT_ID = 1;
vs
DELETE FROM PARENT WHERE PARENT_ID = 1;
zarówno on delete cascade
włączone. Niespodziewanie, w pierwszym przypadku powyżej, Oracle sonduje indeks klucza obcego na tabeli podrzędnej, aby sprawdzić, czy istnieją wiersze, które wymagałyby kaskady. Jeśli nie ma żadnych wierszy, Oracle nie wykonuje kasowanego usunięcia.
Nie można porównać obu opcji, takich jak ta. nie jest to problem z wydajnością, ale bardziej projekt i struktura.
Jeśli projektujesz bazę danych za pomocą kluczy podstawowych/zagranicznych, łatwiej będzie usunąć za pomocą kaskadowania-usuwania niż wyszukiwanie ręcznie, jeśli masz klucze obce, na których kolumnie i tabeli i generujesz instrukcje SQL.
Główną zaletą funkcji kaskadowych-kasuje jest to, że pozwala zmniejszyć ilość zapytań SQL trzeba wykonać usuwać działań
Jeśli chcesz usunąć kaskady i nie mieć klucz obcy zdefiniowane , możesz użyć czegoś takiego:
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)
)
Wadą takiego rozwiązania byłoby to, że wszystkie wstawione wiersze, które sesja, w której usunięto polecenie, nadal będą wstawiane - i osierocone, ponieważ zabiłeś rodzica, ale wiersze podrzędne nadal są wstawiane. –
- 1. Serwer SQL: odpowiednik kaskady kaskadowej?
- 2. Usuwanie blokad w Oracle 10
- 3. Jak korzystać z kaskady usuwania w mysql?
- 4. kaskady i sygnały/gniazda
- 5. Błąd kaskady JPA
- 6. usuwanie milisekund z pola Oracle tmstmp
- 7. Usuwanie kaskady Entity Framework Migration jest zawsze prawdziwe, nawet WillCascadeOnDelete (false) w konfiguracji
- 8. Jak utworzyć migrację Rails, która aktualizuje klucz obcy przy użyciu ograniczenia kaskady na usuwanie?
- 9. Unikanie głęboko zagnieżdżone kaskady opcję w Scala
- 10. Gdzie mogę znaleźć pliki xml kaskady haar?
- 11. Mapowanie NHibernate według kodu (Loquacious) - opcje kaskady
- 12. Serwer Sql - rekursywne usuwanie
- 13. Najszybszy sposób kasowania kaskady wielu obiektów w trybie hibernacji
- 14. procedura oracle zwraca liczbę całkowitą
- 15. Hibernate - Jeden do wielu relacji i sierociniec kaskady Reemoval
- 16. Kaskadowanie w grze Combobox wymaga bardziej szczegółowej kaskady z opcji
- 17. Doctrine 2 kaskady = { „” usuń "} nie wydaje się działać
- 18. Plan wykonania klucza obcego Oracle?
- 19. Oracle developer VM with Oracle 11g
- 20. Oracle SQL vs Oracle PL/SQL
- 21. `pokaż utwórz odpowiednik tabeli` w Oracle Oracle
- 22. usuwanie lub usuwanie ManagedObject w CoreData
- 23. Usuwanie wsadowe hibernacji vs pojedyncze usuwanie
- 24. Oracle "(+)" Operator
- 25. Oracle & Pagination
- 26. Oracle odpowiednik PostgreSQL INSERT ... RETURNING *;
- 27. Jak zmienić strefę czasową Oracle SQL Developer/Oracle Data Modeler?
- 28. Oracle MERGE nie INSERT
- 29. Oracle Analityczne Pytanie
- 30. Połącz SQLPLUS w oracle
+ 1 doskonałe wyjaśnienie Adam –
więc gdzie jest odpowiedź? co jest bardziej wydajne. – magulla
@magulla: Tak jak w przypadku większości rzeczy w Oracle, to zależy. Ręczne usuwanie wielu wierszy podrzędnych może być skuteczniejsze przed usunięciem, ale nic nie stoi na przeszkodzie, aby inna sesja wstawiała więcej dzieci, gdy to się dzieje. Biorąc pod uwagę, że Oracle wydaje usunięcie dla każdego usuniętego wiersza nadrzędnego, jeśli istnieją dzieci, jeśli wydajność jest najważniejsza, zróbmy wszystko, aby usunąć interesujące wiersze tabeli podrzędnej za pomocą pojedynczej instrukcji, ale "lepsza" wydajność nie jest gwarantowana . –