Artikel - Detailansicht

Icon Aktuelles Datenbankoptimierung mit Indizes

Die Zugriffsgeschwindigkeit auf Daten in einer Datenbank ist stark vom Design und Konfiguration der Datenbank abhängig. In diesem Artikel soll jedoch der Fokus auf das richtige Anlegen von Indizes gesetzt werden, da Indizes die Performance einer Datenbank erheblich verbessern können. Bessere Performance der Datenbank führt dann wiederum dazu, dass die CF-Scripte von ColdFusion schneller abgearbeitet werden können und die Gesamtapplikation läuft dadurch schneller und stabiler.
Indizes sind Datenbankobjekte, die Such-, Manipulations- und Sortiervorgänge in Tabellen verbessern sollen. Ein Index ermöglicht der Datenbank, ähnlich wie ein Register in einem Buch, einen schnellen Zugriff auf die Zeilen einer Tabelle.
Indizes sind keine Muss-Bedingung für eine Tabelle. Eine Datenbank funktioniert auch ohne Indizes, aber eben nur langsamer :-). Die Kunst des Indizierens ist es nun, zu entscheiden, welche Spalten einer Tabelle indiziert werden sollten.
Der Artikel kann kein komplettes KnowHow über Tabellenindizierung darlegen. Es sollen lediglich ein paar Ratschläge und Erfahrungen vermittelt werden. In jedem Falle sollte man bei der Indizierung immer Geschwindigkeitsmessungen der SQL-Statements durchführen um die Effektivität der gemachten Änderungen an der Tabelle zu untersuchen.

Indizes werden auf ausgewählte Spalten von Tabellen angewendet. Es muss also zuerst entschieden werden, welche Spalten indiziert werden sollten.
Das ist ein nicht gerade einfacher Schritt, denn welche Spalten Kandidaten für Indizierung sind kann sich von Fall zu Fall und SQL-Statement zu SQL-Statement ändern. Hat man beispielsweise 2 gleiche Tabellen mit den gleichen Daten aber die Selects sind unterschiedlich, wird der optimale Index für die Tabellen nicht der gleiche sein.
Allgemein kann man die Interaktionen eines CF-Scripts mit der Datenbank in 3 Kategorien unterteilen:
  -Daten selektieren
  -Daten einfügen oder updaten
  -Daten löschen

Alle Tabellen sollten irgendwie als Hauptverwendungszweck in diese Kategorien eingeordnet werden. Tabellen, in denen oft Inserts, Update oder Deletes standfinden:

update TUser set dLastLogin='2001-2-1 20:23' where pkUserID=5


Da pkUserID als Spalte in der Where-Bedingung vorkommt, sollte auf pkUserID ein Index liegen. pkUserID ist in diesem Fall aber der Primärschlüssel und die meisten Datenbanken legen dafür sowieso schon einen Index an.

Das Ermitteln von Index-Kanidaten für Select-Statements sind ein bischen komplexer da es hier viel Spielraum gibt. Zuerst solle man sich vor Augen führen, in welcher Reihenfolge die Daten oft sortiert werden:

select * from TUser order by sName

Die Spalte sName ist ein guter Kandidat für einen Index da sie im ORDER BY referenziert wird.

Dann sollte man sich überlegen, welche Spalten in Joins benutzt werden. Oft sind das die Fremdschlüssel einer Tabelle, auf die dann ebenfalls ein Index gehört:

select TUser.sUsername,TUser.dCreatedate,TCategory.sName from TUser
inner join TCategory on TUser.fkCID=TCategory.pkCID


TUser.fkCID ist ein Kandidat für einen Index.

Eine Weitere Überlegung sollte sein, welche Spalten im Select als Suchkriterien vorkommen:

select * from TUser where iSales between 1000 and 3000

Ein Index auf TUser.iSales ermöglicht dem Datenbanksystem schnell auf die benötigten Zeilen zuzugreifen.

Zum Schluss sind auch Spalten interessant, die mit dem LIKE-Operator abgefragt werden:

select * from TUser where sLastName like 'go%'

Ein Index auf TUser.sLastName verbessert die Suchgeschwindigkeit. Allerdings funktioniert der Index nur, wenn der Like-Operator auf den Beginn eines Suchbegriffes angewendet wird. Wenn wir in einem Telefonbuch alle Nummer von Leuten suchen sollen, die mit 'go' anfangen, ist das relativ leicht anhand der sortierten Namen möglich.
Um aber alle Namen aus dem Telefonbuch zu suchen die ein 'go' im Namen irgendwo enthalten, nützt die sortierte Namensliste herzlich wenig.

Ein:

select * from TUser where sLastName like '%go%'

kann also einen Index auf TUser.sLastName nicht nutzen.

Indizes können auch mehrer Spalten beinhalten. Wird oft die Abfrage:

select * from TUser where
fkCID=10 and iSales between 1000 and 3000


verwendet, lohnt sich ein kombinierter Index auf TUser.fkCID und TUser.iSales.
Die Abfrage sollte dann aber auch immer in der Where-Bedingung die gleiche Reihenfolge der Spalten haben (auch wenn viele Datenbanksysteme so inteligent sind, das zu erkennen).

Beim Anlegen von Indizes für eine Tabelle sollte man es jedoch nicht übertreiben. Indizes erfordern Zeit beim Einfügen und Löschen von Daten. Zu viele Indizes in einer Tabelle verschlechtern also auch wieder diese Vorgänge.
Alles hat wie immer Vor- und Nachteile :-)
Den fest vorgeschriebenen Weg gibt es nicht, am Ende muss man also immer überprüfen, ob der gewünschte Erfolg eingetreten ist.

Die Tabelle soll einen kurzen Überblick vermitteln, wo man indizieren könnte und wo nicht:

Kandidaten für Indizes:

  -Primär- und Fremdschlüssel
  -Spalten, die in Joins vorkommen
  -Spalten, die oft in WHERE oder ORDER BY referenziert werden
  -Spalten, deren Werte mittels BETWEEN,>,<, >= oder <= durchsucht werden

Keine Indizes sollte man setzen:
  -Spalten, die mit LIKE und beginnenden Wildcards ( '%abc%') referenziert werden
  -Spalten, die weniger als 3 unterschiedliche Werte enthalten (z.B. Boolean-Typ mit 0 und 1)
  -Spalten, die grösser als 25 Bytes sind
  -Spalten, die Werte enthalten, die in mehr als 20% aller Datensätze vorkommen.

PS: ' select *' sind unperformant und sollten normalerweise nicht wirklich benutzt werden :-)

Steffen Goldfuss steffen@goldfuss.de - 22.02.2001

Zurück


Das deutsche ColdFusion-Forum cfml.de ist das Portal für Einsteiger und Experten zum Thema ColdFusion und der ColdFusion Markup Language (CFML).

© 2017 Webdesign & Hosting: CHC ONLINE Kassel | SOLVA Content-Management-System CMS
Urlaub-Angebote.de - Urlaub mit Bestpreis-Garantie buchen