Home > Datenbanken > MySQL MyISAM – Index oder nicht?

MySQL MyISAM – Index oder nicht?

Für einen Kunden habe ich mich in letzter Zeit etwas eingehender mit dem Datenbank Backend befasst. Ein Setup mit mehreren Servern, Synchronisierung und Lastverteilung existierte bereits. Jedoch konnte ich den Logfiles entnehmen, dass es hin und wieder Anfragen an den Datenbankserver gibt, die extrem lange Dauern und dadurch andere Anfragen durch Sperren behindern. Bei der Analyse bin ich auf ein paar interessante Details gestoßen.

Der Kunde hat für das Staging seiner Webanwendung zwei unterschiedliche Server. Sowohl Hardware als auch Betriebsystem sind identisch eingerichtet. Die Konfigurationsdatei für die Datenbanken sind ebenfalls gleich. Der Unterschied ist jedoch, dass auf einem System ein und die selbe Anfrage 1 Sekunde benötigt. Auf dem anderen System wartet man bis zu 5000 Sekunden. Ein EXPLAIN mit dem MySQL Client brachte nur die Gewissheit: Der existierende Index wird auf dem einen System nicht verwendet.

mysql> EXPLAIN (eine SELECT Anfrage)
+-------+--------+---------------+---------+---------+----------------+--------+---------------------------------+
| table | type   | possible_keys | key     | key_len | ref            | rows   | Extra                           |
+-------+--------+---------------+---------+---------+----------------+--------+---------------------------------+
| p     | ALL    | idx_on_column | NULL    |    NULL | NULL           | 3588047| Using temporary; Using filesort |
+-------+--------+---------------+---------+---------+----------------+--------+---------------------------------+

Erst stand der Verdacht im Raum, dass der Index auf dem einen System nicht in den Arbeitsspeicher passt, und aus diesem Grund nicht verwendet wird. Doch ausreichend Arbeitsspeicher stand zur Verfügung. Dann erinnerte ich mich vage, dass ich mal etwas in der MySQL Dokumentation zum Thema Index gelesen hatte. Die Kardinalität eines Index sollte nach dem Anlegen mit Hilfe von ANALYZE TABLE bzw. mysqlcheck neu berechnet werden.

mysqlcheck -u USER -p PASSWORD --analyze DB_NAME [TABLE_NAME]

Und tatsächlich wurde ab diesem Moment der entsprechende Index für die Anfrage verwendet. Mit Hilfe der Kardinalität kann MySQL entscheiden, ob ein Index für eine Anfrage verwendet werden kann, oder nicht. Bei fehlerhafter Kardinalität kann es vorkommen, dass die Entscheidung über das für und wider eines Index falsch getroffen werden.

Diese Art der Nachhilfe braucht MySQL allerdings nur beim Tabellentyp MyISAM. Der neuere Typ InnoDB ist deutlich besser in der Lage auszuwerten, ob und welche Indizes für eine bestimmte Anfrage benutzt werden können.

  1. Bisher keine Kommentare
  1. Bisher keine Trackbacks