Tuning für ein Delete

Hi!

Ich habe derzeit ein kleines Laufzeit-Problem mit einem Delete. Vielleicht kann mir jemand von euch einen Tuning-Tipp geben:

Eine Tabelle („Bestand“) enthält ca. 200.000 Datensätze mit einem Primary Key auf „ID“.
Eine zweite Tabelle („To_Delete“) enthält die IDs der aus „Bestand“ zu löschenden Datensätze (ca. 50.000 Datensätze, nicht indiziert).

Nun soll ein bestimmter Nummernkreis aus „Bestand“ gelöscht werden. Das SQL dazu sieht so aus:

Delete from Bestand
where ID between 4000 and 20000
and ID in
(Select Del_ID from To_Delete
where Del_ID between 4000 and 20000)

Das SQL braucht endlos lange (ohne die „between“-Klauseln steigt die Datenbank sogar aus!). Kann man das SQL optimieren? Nutzt eine Indizierung der To_Delete bzw. ein order by im Select auf die To_Delete?

Danke schon mal für jeden Tipp!

Heinrich

hi!

Nutzt eine Indizierung der To_Delete

Na auf jeden Fall!
Das ist ein himmelweiter Unterschied. Schließlich muß für jeden Datensatz die Löschliste durchgegangen werden, ob die ID vorhanden ist.

Hab mir interessehalber eben die Zeit genommen, das hier auszuprobieren.
Dazu hab ich ebenfalls 200.000 Dummy-Datensätze erstellt, allerdings nur 1000 Löscheinträge.

Ohne Index dauerte das Spielchen über 5 Minuten, mit Index hingegen satte 0,52 Sekunden ^^

CU!

Hi1

Delete from Bestand
where ID between 4000 and 20000
and ID in
(Select Del_ID from To_Delete
where Del_ID between 4000 and 20000)

Wozu zweimal das „ID between“??

Warum wird in der To_Delete-Tabelle überhaupt eingeschränkt?

Reicht nicht ein

delete from Bestand
where ID in (select Del\_ID from To\_Delete)

Normalerweise wird das Subselect einmal aufgebaut und die Ergebnismenge bleibt dann im Cache. Ein Index auf die ID UND auf die DEL_ID wäre natürlich von erheblichsten Vorteil.

Grüße,
Tomh

PS: Welches RDBMS?

Hi!

Delete from Bestand
where ID between 4000 and 20000
and ID in
(Select Del_ID from To_Delete
where Del_ID between 4000 and 20000)

Wozu zweimal das „ID between“??

Stimmt. Erstes between ist überflüssig

Warum wird in der To_Delete-Tabelle überhaupt eingeschränkt?

Reicht nicht ein

delete from Bestand
where ID in (select Del_ID from To_Delete)

Nein. Die To_Delete enthält mehr als die IDs von 4000 bis 20000 - und nur dieser Bereich soll gelöscht werden.

PS: Welches RDBMS?

Oracle

Grüße
Heinrich