Ich sehe ständig Leute sagen, dass Indizes langsamer werden update
, delete
und 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 User
Tabelle 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 index
außer für gefilterte Indizes ...Antworten:
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.
quelle
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:
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.
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.
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.
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.
quelle
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.
quelle