Ich habe eine SQL Server 2005-Datenbank, und ich habe versucht, Indizes auf die entsprechenden Felder setzen, um die DELETE
Datensätze aus einer Tabelle mit Millionen von Zeilen zu beschleunigen (big_table
hat nur 3 Spalten) , aber jetzt ist die DELETE
Ausführungszeit sogar länger! (1 Stunde gegenüber 13 Minuten zum Beispiel)SQL Server DELETE ist langsamer mit Indizes
Ich habe eine Beziehung zwischen Tabellen, und die Spalte, die ich filtere meine DELETE
von ist in der anderen Tabelle. Zum Beispiel
DELETE FROM big_table
WHERE big_table.id_product IN (
SELECT small_table.id_product FROM small_table
WHERE small_table.id_category = 1)
Btw, ich habe auch versucht:
DELETE FROM big_table
WHERE EXISTS
(SELECT 1 FROM small_table
WHERE small_table.id_product = big_table.id_product
AND small_table.id_category = 1)
und während es etwas schneller als die erste zu laufen scheint, ist es noch viel langsamer mit den Indizes als ohne.
I erstellten Indizes auf diesen Feldern:
big_table.id_product
small_table.id_product
small_table.id_category
Meine LDF-Datei während der DELETE
viel wächst.
Warum sind meine DELETE
Abfragen langsamer, wenn ich Indizes auf meinen Tabellen habe? Ich dachte, sie sollten schneller laufen.
UPDATE
Okay, Konsens scheint Indizes wird eine riesige DELETE
verlangsamen becuase der Index aktualisiert werden muss. Obwohl, ich verstehe immer noch nicht, warum es nicht alle DELETE
alle Zeilen auf einmal, und aktualisieren Sie den Index nur einmal am Ende.
Ich war unter dem Eindruck von einigen meiner Lesung, dass Indizes DELETE
beschleunigen würde, indem die Suche nach Feldern in der WHERE
Klausel schneller.
„Indizes arbeitet auch nur, wenn für einen Datensatz in DELETE und UPDATE-Befehlen suchen, wie sie für SELECT-Anweisungen zu tun.“
Aber später in dem Artikel heißt es, dass zu viele Indizes die Leistung beeinträchtigen können.
Antworten auf Bob Fragen:
- 55 Millionen Zeilen in Tabelle
- 42 Millionen Zeilen würde System nicht ausgeführt
- ähnliche
SELECT
Anweisung gelöscht werden (Ausnahme vom Typ‘.OutOfMemoryException‘geworfen wurde)
ich die folgenden zwei Abfragen versucht:
SELECT * FROM big_table
WHERE big_table.id_product IN (
SELECT small_table.id_product FROM small_table
WHERE small_table.id_category = 1)
SELECT * FROM big_table
INNER JOIN small_table
ON small_table.id_product = big_table.id_product
WHERE small_table.id_category = 1
Beide gescheitert nach für 25 min laufen mit dieser Fehlermeldung von SQL Server 2005:
An error occurred while executing batch. Error message is: Exception of type 'System.OutOfMemoryException' was thrown.
Der Datenbankserver ist eine ältere Dual-Core-Xeon-Maschine mit 7,5 GB RAM. Es ist meine Spielzeug-Test-Datenbank :) Es läuft also nichts anderes.
Muss ich etwas spezielles mit meinen Indizes tun, nachdem ich sie CREATE
richtig arbeiten lasse?
Wie viele Zeilen sind in der Tabelle zu vermeiden? Wie viele Zeilen werden gelöscht? Wie lange würde eine ähnliche SELECT-Anweisung dauern? Wenn Sie wissen, wie schnell die SELECT-Anweisung ausgeführt wird, erhalten Sie möglicherweise einen Einblick, wie sich die Indizes auf DELETE auswirken. – bobs
55 Mil Zeilen, 42 gelöscht, nicht abgeschlossen, siehe oben für weitere Details – JohnB
Es dauert länger, da beim Ausführen eines Löschvorgangs die Indizes, die sich auf Ihre Tabelle beziehen, ebenfalls aktualisiert werden müssen. – WOPR