Obwohl das Durchwandern des Indexbaumes sehr effektiv ist, kann eine Indexsuche trotzdem langsam sein. Dieser Widerspruch wird oft auf den Mythos vom „defekten Index“ zurückgeführt. Dieser Mythos verspricht eine Wunderheilung, wenn man den Index neu anlegt. Anhang B, „Mythen-Verzeichnis“ behandelt diesen und andere Mythen. Man kann jedoch vorwegnehmen, dass das Neuaufbauen die Index-Performance nicht nachhaltig verbessert. Die wahre Ursache eines „langsamen Indexes“ kann man anhand der Index- und Tabellenstruktur erklären.
Die erste Zutat zu einem langsamen Index ist die Blattknoten-Kette. Betrachten wir dazu nochmal die Suche nach dem Wert „57“ in Abbildung 1.3. Offenbar gibt es für diese Suche zwei Treffer. Um genau zu sein, mindestens zwei Treffer. Denn der nächste Blattknoten könnte noch weitere Einträge für „57“ enthalten. Die Datenbank muss also den nächsten Blattknoten laden und auf weitere Treffer prüfen. Bei einem Indexzugriff muss die Datenbank also nicht nur den Baum durchwandern, sondern auch die Blattknoten-Kette verfolgen.
Hinweis in eigener Sache
Ich biete SQL Schulungen, Optimierung und Beratung an. Auch der Kauf meines Buches „SQL Performance Explained“ (ab €9,95) unterstützt meine Arbeit an dieser Webseite.
Die zweite Zutat zu einem langsamen Index ist der Tabellenzugriff. Denn selbst ein einzelner Blattknoten kann viele Treffer liefern – oft hunderte. Die entsprechenden Tabellenzugriffe sind dann oft auf viele Datenblöcke verteilt (siehe Abbildung 1.1). Das bedeutet, dass für jeden Treffer noch ein Tabellenzugriff notwendig ist.
Insgesamt besteht ein Indexzugriff also aus drei Schritten: (1) das Durchwandern des Baumes; (2) das Verfolgen der Blattknoten-Kette; (3) der Tabellenzugriff. Aber nur beim ersten Schritt gibt es durch die Baumstruktur eine Obergrenze für die Anzahl der Lesezugriffe. Für die anderen Schritte müssen unter Umständen sehr viele Blöcke gelesen werden. Durch diese Schritte kann ein Indexzugriff langsam werden.
Der Mythos des defekten Indexes hat seinen Ursprung im Irrglauben, dass ein Indexzugriff nur den Baum durchwandern muss und daher immer schnell ist. Daraus folgt dann, dass ein langsamer Indexzugriff von einem „defekten“ oder „entarteten“ Index verursacht werden muss. Die Wahrheit ist, dass man Datenbanken sogar fragen kann, welche Schritte sie für einen Indexzugriff durchführen. Die Oracle Datenbank ist in diesem Zusammenhang besonders mitteilsam und hat für einen Indexzugriff gleich drei Operationen:
- INDEX UNIQUE SCAN
Der
INDEX UNIQUE SCAN
durchwandert nur den Index-Baum. Die Oracle Datenbank verwendet diese Operation, wenn ein Constraint sicherstellt, dass maximal ein Eintrag dem Abfragekriterium entspricht.- INDEX RANGE SCAN
Der
INDEX RANGE SCAN
durchwandert den Index-Baum und folgt anschließend der Blattknoten-Kette, um alle Treffer zu finden. Diese Operation wird verwendet, wenn mehrere Treffer möglich sind.- TABLE ACCESS BY INDEX ROWID
Lädt eine Zeile anhand einer
ROWID
aus der Tabelle. Diese Operation wird für jeden Treffer der vorangegangen Indexoperation durchgeführt.
Wichtig ist, dass ein INDEX RANGE SCAN
potenziell einen sehr großen Teil des Indexes lesen muss. Wenn dann noch ein Tabellenzugriff für jede Zeile durchgeführt wird, kann eine Abfrage trotz Index sehr langsam sein.