it-swarm.com.de

Was ist besser für große Änderungen an einer Tabelle: LÖSCHEN und EINFÜGEN jedes Mal oder UPDATE vorhanden?

Ich mache ein Projekt, bei dem ich täglich etwa 36.000 Datensätze in einer Tabelle ändern muss. Ich frage mich, was besser abschneiden wird:

  1. zeilen löschen und neue einfügen, oder
  2. aktualisieren Sie bereits vorhandene Zeilen

Für mich ist es einfacher, einfach alle Zeilen zu löschen und neue einzufügen. Wenn dies jedoch die Tabelle und die Indizes fragmentiert und die Leistung beeinträchtigt, würde ich es vorziehen, wenn möglich Aktualisierungen vorzunehmen und nur bei Bedarf zu löschen/einzufügen.

Dies wird ein nächtlicher Service sein und ich möchte die Geschwindigkeit des Prozesses selbst nicht verbessern. Ich bin mehr besorgt über die Leistung von Abfragen für diese Tabelle im Allgemeinen, wo ich bereits 89 Millionen Datensätze habe, und darüber, wie sich dieser nächtliche Prozess darauf auswirken wird.

Soll ich Datensätze löschen/einfügen oder vorhandene (soweit möglich) für diesen nächtlichen Prozess aktualisieren?

27
adopilot

Es hängt wirklich davon ab, wie viel sich die Daten ändern. Nehmen wir an, diese Tabelle enthält 20 Spalten. Und Sie haben auch 5 Indizes - jeder auf einem Diff. Säule.

Wenn sich nun die Werte in allen 20 Spalten ändern OR, auch wenn sich die Daten in 5 Spalten ändern und diese 5 Spalten alle indiziert sind, ist es möglicherweise besser, "zu löschen und einzufügen". Aber wenn Es ändern sich nur zwei Spalten. Nehmen wir an, diese sind nicht Teil eines nicht gruppierten Index. Dann ist es möglicherweise besser, die Datensätze zu "aktualisieren", da in diesem Fall nur der gruppierte Index aktualisiert wird (und die Indizes nicht aktualisiert werden müssen) ).


Bei weiteren Untersuchungen stellte ich fest, dass der obige Kommentar von mir redundant ist, da SQL Server intern über zwei separate Mechanismen zum Ausführen eines UPDATE verfügt. - Ein "In-Place-Update" (dh durch Ändern eines Spaltenwerts in einen neuen in der ursprünglichen Zeile) oder als "Nicht-In-Place-UPDATE" (DELETE, gefolgt von einem INSERT).

In-Place-Updates sind die Regel und werden nach Möglichkeit durchgeführt. Hier bleiben die Zeilen im gleichen Umfang genau an derselben Stelle auf derselben Seite. Nur die betroffenen Bytes werden verwaltet. Das tlog hat nur einen Datensatz (vorausgesetzt, es gibt keine Update-Trigger). Aktualisierungen erfolgen an Ort und Stelle, wenn ein Heap aktualisiert wird (und auf der Seite genügend Speicherplatz vorhanden ist). Aktualisierungen erfolgen auch, wenn sich der Clustering-Schlüssel ändert, die Zeile jedoch überhaupt nicht verschoben werden muss.

Zum Beispiel: Wenn Sie einen Clustered-Index für den Nachnamen haben und die Namen: Able, Baker, Charlie Jetzt möchten Sie Baker auf Becker aktualisieren. Es müssen keine Zeilen verschoben werden. Dies kann also geschehen. Wenn Sie Able auf Kumar aktualisieren müssen, müssen die Zeilen verschoben werden (obwohl sie sich auf derselben Seite befinden). In diesem Fall führt SQL Server ein DELETE gefolgt von einem INSERT aus.

In Anbetracht des oben Gesagten würde ich vorschlagen, dass Sie ein normales UPDATE durchführen und SQL Server den besten Weg finden, dies intern zu tun.

Weitere Informationen zu "UPDATE" -Internalen oder zu SQL Server-bezogenen Interna finden Sie im Buch von Kalen Delaney, Paul Randal et al. - SQL Server 2008 Internals .

10

Haben Sie den Befehl MERGE in SQL 2008 untersucht? Hier ist ein grundlegendes Beispiel:

  merge YourBigTable ybt
  using (select distinct (RecordID) from YourOtherTable) yot
     on yot.Recordid = YBT.RecordID
  when NOT matched by target
  then  insert (RecordID)
        values (yot.DeviceID) ;

Dies ist im Grunde ein "UPSERT" -Befehl. Aktualisieren Sie, falls vorhanden, und fügen Sie es ein, wenn dies nicht der Fall ist. Sehr schneller, sehr cooler Befehl.

8
datagod

Aber ich selbst habe das Löschen und Einfügen gegen Aktualisieren in einer Tabelle mit 30 Millionen (3 Crore) Datensätzen überprüft. Diese Tabelle enthält einen gruppierten eindeutigen zusammengesetzten Schlüssel und 3 nicht gruppierte Schlüssel. Das Löschen und Einfügen dauerte 9 Minuten. Für das Update dauerte es 55 Minuten. In jeder Zeile wurde nur eine Spalte aktualisiert.

Also bitte ich Sie, nicht zu raten. Die Gleichungen ändern sich, wenn es sich um eine große Tabelle mit vielen Spalten und vielen Daten handelt.

4
srinivas

Das Update ist nicht so schnell. Der Trick besteht darin, ein schnelles Einfügen zu erreichen, indem die Indizes deaktiviert werden, während Daten eingefügt werden.

Erwägen Sie Folgendes:

-- disable indexes
ALTER INDEX [index_name] ON dbo.import_table DISABLE
-- ... disable more indexes

-- don't use delete if you don't care about minimal logging. truncate is faster
TRUNCATE TABLE dbo.import_table

-- just insert the new rows
INSERT dbo.import_table
SELECT
    *
FROM
    dbo.source_table

-- rebuild indexes
ALTER INDEX [index_name] ON dbo.import_table REBUILD
-- ... rebuild more indexes

Noch schneller ist es, die automatische Statistikaktualisierung in den Datenbankoptionen zu deaktivieren. Wenn die Tabelle erheblich geändert wird, sollten Sie Folgendes ausführen:

UPDATE STATISTICS dbo.import_table

oder

EXEC sp_updatestats

als Job regelmäßig (täglich, wöchentlich, abhängig von der Datenbankgröße), um die Statistiken auf dem neuesten Stand zu halten. Achten Sie darauf, dass Sie die Statistiken aktualisieren, wenn die Tabelle leer ist. Das wird die Statistiken vermasseln, wenn Sie sie nicht ausführen, nachdem die Tabelle erneut gefüllt wurde.

3
Asken