Auswirkung eines Index auf Aktualisierungsanweisungen, bei denen sich die Aktualisierungsspalte nicht in einem Index befindet


16

Ich sehe ständig Leute sagen, dass Indizes langsamer werden update, deleteund insert. Dies wird als pauschale Aussage verwendet, als ob es ein absolutes ist.

Während ich meine Datenbank optimiere, um die Leistung zu verbessern, stoße ich immer wieder auf eine Situation, die dieser Regel logisch zu widersprechen scheint, und nirgendwo kann ich jemanden finden, der etwas anderes sagt oder erklärt.

In SQL Server, und ich glaube, die meisten anderen DBMS, werden Ihre Indizes basierend auf bestimmten von Ihnen angegebenen Spalten erstellt. Einfügungen und Löschungen wirken sich immer auf eine ganze Zeile aus, sodass sie sich nicht auf den Index auswirken. Aktualisierungen wirken jedoch etwas eindeutiger, da sie nur bestimmte Spalten betreffen können.

Wenn ich Spalten habe, die in keinem Index enthalten sind, und diese aktualisiere, werden sie verlangsamt, nur weil ich einen Index für andere Spalten in dieser Tabelle habe?

Nehmen wir zum Beispiel an, ich habe in meiner UserTabelle einen oder zwei Indizes, den Primärschlüssel, der eine Identity / Auto Increment-Spalte ist, und möglicherweise einen anderen in einer Fremdschlüsselspalte.
Wenn ich eine Spalte aktualisiere, auf der sich der Index nicht befindet, z. B. Telefonnummer oder Adresse, wird diese Aktualisierung verlangsamt, weil ich in beiden Situationen Indizes für diese Tabelle in anderen Spalten habe? Die Spalten, die ich aktualisiere, befinden sich nicht in Indizes. Daher sollten die Indizes logischerweise nicht aktualisiert werden, oder? Wenn überhaupt, würde ich denken, dass sie beschleunigt werden, wenn ich die Indizes in der WHERE-Klausel verwende.


so there is no way they will not affect the indexaußer für gefilterte Indizes ...
usr

Ich stelle mir den nicht abgedeckten, nicht gruppierten Index so vor, dass er Zeiger auf Datensätze enthält (normalerweise in den gruppierten Indexblattknoten der Tabelle). Ich würde denken, dass eine Situation, die eine Verlangsamung während eines UPDATE (eines nicht eingeschlossenen Attributs) verursacht, eine Situation sein könnte, in der das UPDATE den Datensatz veranlasst hat, sich innerhalb des Clustered-Index zu bewegen. Ich bin mir immer noch nicht sicher, ob eine Bewegung den Zeiger ändern würde, ODER ob der Zeiger einfach ein KEY-Wert in den Clustered-Index ist. In diesem Fall wäre die mögliche Standortaktualisierung nicht von Bedeutung, da das System nur eine KEY-Suche durchführen würde um den Rekordwert zu erhalten.
Jmoney38

Antworten:


6

Sie haben Recht, dass das Aktualisieren einer nicht indizierten Spalte keine Änderungen an den Indizes verursacht. In einem einfachen Fall würde es auch keine Gesamtauswirkung auf den Tisch geben.

Wenn eine Abfrage den Index zum Nachschlagen von Daten verwenden kann, kann dies die Suche beschleunigen, das genaue Verhalten (abhängig von Ihrer SQL-Marke) kann sich jedoch von dem anderer SQL-Marken unterscheiden. (Ich verwende hauptsächlich Microsoft SQL Server.)

Das Aktualisieren einer Spalte mit einem erheblich größeren Datenvolumen kann natürlich dazu führen, dass Zeilen auf andere Seiten verschoben werden.


1
SQL Server wird im OP erwähnt, ich habe ein Tag hinzugefügt, daher kann man davon ausgehen, dass SQL Server
Tom V - Team Monica am

10

Für ein relativ schnelles modernes System ist das Hinzufügen eines einzelnen Index zu einer OLTP-Tabelle unter dem Gesichtspunkt der Leistung für die überwiegende Mehrheit der Systeme wahrscheinlich praktisch nicht nachweisbar . Sie sollten jedoch keine unnötigen Indizes erstellen, und Sie sollten wahrscheinlich keine einspaltigen Indizes für jede Spalte in einer Tabelle erstellen.

Sie gehen zu Recht davon aus, dass das Vorhandensein nützlicher Indizes bei vielen Abfragen zu einer spürbaren Geschwindigkeitsverbesserung führt.

Obwohl sich Ihre Frage anscheinend um die Leistung dreht, gibt es einige andere potenzielle Probleme beim Hinzufügen von Indizes, unter anderem:

  1. Die zum Erstellen des Index erforderliche Zeit kann zum Blockieren führen, während der Index der Tabelle hinzugefügt wird. Das Schloss ist sehr kurzlebig und wird höchstwahrscheinlich kein großes Problem verursachen.

  2. Indexänderungen führen dazu, dass Ausführungspläne für alle Pläne ungültig werden, die auf die zugrunde liegende Tabelle verweisen. Wenn diese Ausführungspläne erneut kompiliert werden, kann sich die Leistung bei einigen Abfragen negativ ändern.

  3. Indexänderungen können dazu führen, dass Abfragen Fehler zurückgeben, bei denen zuvor keine zurückgegeben wurden. Nehmen Sie den Fall eines gefilterten Index, der verwendet wurde, um in einem varchar-Feld enthaltene Daten zurückzugeben. Wenn der Filter Zeilen entfernt hat, bei denen es sich nicht um Datumsangaben handelt, und dieser Filter anschließend geändert wird, schlagen Abfragen, die sich auf diesen Index stützen, möglicherweise fehl, wenn versucht wird, Nicht-Datumsdaten zu konvertieren.

  4. Ein neuer Index kann dazu führen, dass sich die Ausführungsreihenfolge ändert, was zu möglichen Deadlocks führt, wenn sie zuvor nicht aufgetreten sind.


"Der Codepfad, der für eine Aktualisierung erforderlich ist, wenn der Index nicht betroffen sein soll, muss noch ausgewertet werden." Dies ist nicht der Fall. Die Kompilierungs- / Optimierungsphase weiß sehr genau, welche Indizes gegebenenfalls aktualisiert werden müssen, und erstellt den Plan entsprechend. Eine UPDATE-Anweisung, die Spalten in einem Index (einschließlich INCLUDE- und Clustered-Key-Spalten) nicht ändert (in der SET-Liste deklariert), muss diesen Index nicht aktualisieren, und die Ausführungsphase wird ihn nicht einmal berühren. DELETE und INSERT berühren offensichtlich alle Spalten (logisch) und müssen alle Indizes aktualisieren.
Remus Rusanu

@RemusRusanu, aber muss es nicht ausgewertet werden, wenn der Index zum Auffinden der zu aktualisierenden Zeilen verwendet werden kann?
Tom V - Team Monica

@RemusRusanu - Ich nehme an, sobald der QO einen Plan erstellt hat, wird keine CPU mehr benötigt. Um den Plan zu kompilieren, muss er dies jedoch tun. Wenn Pläne häufig erstellt werden, kann dies einen geringfügigen Unterschied bewirken.
Max Vernon

@TomV Verwenden des Index zum Auffinden der zu löschenden / zu aktualisierenden Kandidatenzeile (n) ist ein ganz anderes Thema. In diesem Fall sollten die Vorteile des Lokalisierens der Zeilen über einen Index alle Probleme mit den Indexwartungskosten überwinden.
Remus Rusanu

@MaxVernon Ich würde argumentieren, dass es kein gültiges Szenario für häufige Neukompilierungen von DML (UPDATE) gibt. Ich kaufe einige Fälle für gültige (unvermeidbare?) Neukompilierungen für Ad-hoc-Abfragen. Aber DML? Welche Art von App könnte ad-hoc eindeutige UPDATE-Anweisungen erstellen? Häufige Neukompilierungen mit DML rufen laut "Parametrisiere mich".
Remus Rusanu

-2

Wenn die Aktualisierungsoperation auf eine nicht indizierte Spalte fester Größe (wie eine Ganzzahl) abzielt, sollte sie im Allgemeinen nicht langsam sein, aber im Vergleich zu einer select-Anweisung muss die Aktualisierung eventuell auch auf die langsame Festplatte geschrieben werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.