Ein Kollege meldete sich vor einigen Wochen mit einem interessanten Problem: Beim Löschen von Objekten aus einem komplexeren und gut befüllten Datenmodell liefen alle DELETEs in den Subtabellen und Kreuzreferenzen mit der erwarteten Geschwindigkeit (also im niedrigen Millisekundenbereich) ab, aber die DELETEs auf der Haupttabelle benötigten je Objekt dann plötzlich einige Sekunden.
Mehrere Stunden brüteten wir zusammen mit Kollegen über dem Problem, untersuchten den Ausführungsplan der DELETE-Anweisung, misteten Indizes aus, erstellten andere Indizes neu, reorganisierten die betroffene Tabelle… alles ohne Ergebnis.
Erst ein weiterer Blick auf den Ausführungsplan, diesmal ohne Beachtung der angeblichen Aufwandsverteilung, führte dann zur Lösung: In einer anderen Tabelle mit mehreren Millionen Einträgen befand sich eine Fremdschlüsselspalte, die jedoch nicht Indiziert war. Folglich musste für jedes DELETE eine Full-Table-Scan ausgeführt werden um eventuelle Abhängigkeiten auszuschließen.
Daher nun die kurze Merkregel:
Lege auf einer Fremdschlüsselspalte immer auch einen Index an (sofern sie nicht schon führend in einem anderen Index enthalten ist). Sind in der Tabelle nur wenig Daten, dann tut der zusätzliche Index nicht weh, sind in der Tabelle jedoch viele Daten, dann wird man spätestens beim DELETE in der referenzierten Tabelle froh um den Index sein.
Und wie immer: Trotz Merkregel kann es in Einzelfällen gute Gründe geben, sich anders zu verhalten.