Seitenanfang

mySQL Geschwindigkeit verdoppeln

Dieser Post wurde aus meiner alten WordPress-Installation importiert. Sollte es Darstellungsprobleme, falsche Links oder fehlende Bilder geben, bitte einfach hier einen Kommentar hinterlassen. Danke.


Ein guter Datenbankexperte kann jedes Quentchen Geschwindigkeit aus einer Datenbank herausquetschen und ungeahnte Leistung freisetzen. Normalsterblichen bleibt häufig nur das Fluchen und der zweifelhafte Versuch die fehlende Optimierung durch Hardwareupgrades wett zu machen.Zugegeben, der Titel ist etwas hoch gegriffen: Nicht bei jedem Projekt und jeder Datenbank läßt sich die Geschwindigkeit verdoppeln, aber in vielen Fällen ist dies mit ganz einfachen Mitteln möglich. Wer den ersten Abschnitt, die Hardware, übersteht überspringt wird mit Tipps belohnt die sich meist ohne Kosten und mit sehr wenig Zeitaufwand umsetzen lassen.

Tuning für Faule: Hardware

Doch erst einmal zurück zu den Hardwareupgrades: Eine Zeit lang gelingt diese Taktik, für ein rentabel laufendes Projekt werden dann gerne mal 16 oder 24 CPU-Kerne und 128 GB Arbeitsspeicher in einen Datenbankserver verbaut. Mit Hyperthreading lässt sich so ein Server sogar noch auf 48 Kerne schönrechnen. Heutige Computer wie Server werden über diese beiden Größen definiert: Prozessoren und Arbeitsspeicher. Sicherlich sind gute Werte in beiden Kategorien nicht falsch, aber dennoch darf man die I/O-Performance nicht aus den Augen verlieren, dann diese bremst viel häufiger. Viele Betroffene (vor allem kleinerer Projekte) haben bei diesem Thema häufig Fragezeichen in den Augen: Ei was?

Ein ganz kurzer Exkurs in den Grundaufbau eines Computers: Daten müssen irgendwo gespeichert werden, dieser mysteriöse Platz wird in Expertenkreisen "Festplatte" genannt, aber auch Laien hören gelegentlich davon. Eine 100-Terrabyte-Festplatte kann allerdings unverständlicherweise nicht ihren vollen Inhalt jederzeit ohne Zeitverlust zur Verfügung stellen, sondern unterliegt gewissen physikalischen Grenzen.

Anders gesagt: Jedes Byte, dass der mySQL-Server von der Festplatte anfordern muss, braucht Zeit und im Vergleich zu allen anderen Komponenten benötigen Festplatten eine kleine Computer-Ewigkeit um ihre gespeicherten Daten zu liefern. Eine Herde von 10 Festplatten mit je 80 oder 120 Gigabyte erreicht eine (theoretisch) die 10fache Geschwindigkeit einer einsamen 1 Terrabyte-Festplatte, aber auch 2x 500 GB oder 4x 250 GB erreichen ein massives Geschwindigkeitsplus. Dabei macht eine Aufrüstung der Festplattenanzahl vor allem bei großen Datenbeständen meist mehr Sinn als zusätzliche CPU-Kerne oder (viel) mehr RAM.

Der Index, das unbekannte Wesen

Ist die Hardware bis zum Ende der eigenen technischen oder finanziellen Möglichkeiten optimiert, lohnt sich durchaus ein Blick auf die Software denn hier steckt noch wesentlich mehr Potential. Genau genommen sollte dieser Schritt an erster Stelle stehen, denn Software-Optimierungen sind häufig einfacher möglich und vor allem kostenlos (wenn man sie selbst umsetzen kann).

Zu einem guten Datenbankdesign gehören die richtigen Indices, Voraussetzung für deren Definition ist allerdings ein bisschen Fachwissen über die mySQL-Indexbehandlung. Im Gegensatz zu richtigen großen Datenbanken unterstützt mySQL nur einen einzigen Index bei der Verarbeitung einer Anfrage. Die simple Grundregel vieler anderer Datenbanken, alle halbwegs sinnvollen Felder mit einem eigenen Index zu belegen, greift hier nicht. Statt dessen müssen die eigenen Queries analysisert werden: Welche Spalten werden in WHERE-Bedingungen und ORDER BY bzw. GROUP BY Modifikationen verwendet?

Nehmen wir eine Tabelle mit drei relevanten Spalten an: id, a und b. Alle weiteren Spalten werden nicht oder nur sehr selten in WHERE, ORDER BY und GROUP BY verwedenet. Ein Index auf "id" - dem primary key - wird automatisch erstellt, aber Zugriffe auf a oder b ohne gleichzeitigen Zugriff auf id führen zu einem kompletten Scan der Tabelle. Wird jetzt ein Index auf "a, b, id" definiert, so kann dieser vom Anfang zum Ende hin verwendet werden und nicht anders, dass heißt:

    1. WHERE a = ? nutzt den Index (a ist als erstes angegeben)
    2. WHERE b = ? nutzt den Index NICHT, denn b ist nicht am Anfang des Indices verfügbar.
    3. WHERE a = ? AND b = ? nutzt den Index, denn a und b sind beide ohne Unterbrechung am Anfang definiert
Um festzustellen ob mySQL einen Index tatsächlich benutzt, kann der EXPLAIN SELECT - Befehl verwendet werden, in unserem Beispiel könnte EXPLAIN SELECT * FROM table WHERE a = 1 zu Tage bringen, dass der Index gar nicht genutzt wird, beispielsweise weil die Tabelle so klein ist dass mySQL einen kompletten Table-Scan als bessere Möglichkeit ansieht. Es gibt keine Möglichkeit intuitiv festzustellen, ob ein Query einen Index benutzt, also einfach mal EXPLAIN ausprobieren, das Ergebnis ist eine verblüffend schnelle und einfache Diagnose.

Sind Indices in ausreichender Menge und mit den richtigen Spalten vorhanden, hilft ein klassisches Profiling bei der Identifizierung aufwendiger Queries, aber dazu gibt es irgendwann einen eigenen Post...

Fast jedes mySQL-basierte Projekt verzichtet weitgehend oder sogar ganz auf Indices, dabei kann ein Index die Ausführung eines mehrere Minuten langen Query durchaus auf unter eine Sekunde drücken. Zu viele indizierte Spalten können den Server beim Schreiben zwar ausbremsen, die Verzögerungen beim Lesen sind allerdings meist viel gravierender.

Die richtigen Fragen stellen

Bei selbst geschriebenem Sourcecode sollte auch ein kritisches Auge auf häufig jedes benutzte mySQL-Query geworfen werden. Viele Programmierer behandeln Datenbanken leider immer noch wie Variablen, hunderte oder sogar tausende Abfragen für eine einzige Standardseite sind leider keine Seltenheit. Werden hier per Software nur 10% der Zugriffe eingespart, läuft das System insgesamt schneller, denn die Belastung der Datenbank sinkt erheblich und damit steigt die Geschwindigkeit der tatsächlich notwendigen übrigen Queries.

Dabei kann ein kleines Bisschen Caching durchaus erhebliche Vorteile bringen: Ein SELECT COUNT(*) FROM users WHERE email_checked = 1 AND locked = 0 kann auch einmal stündlich/täglich oder nur nach jeder tatsächlichen Änderung (auf den Scripten zur Email-Überprüfung und Userverwaltung) aufgerufen und das Ergebnis in einer Tabelle, auf der Festplatte oder bei persistenten Interpretern auch im RAM gespeichert werden.

Fehlt nur noch der übliche Hinweis: Die beschriebenen Szenarien und Empfehlungen gelten für viele, aber natürlich nicht für alle Projekte und Situationen. Wie immer erfolgt die Umsetzung auf eigene Gefahr. Wer dennoch meint, alles ohne eigenes Nachdenken kopieren zu müssen, sollte den Stecker seines Servers ziehen, das erspart Fast alle Probleme.

 

Noch keine Kommentare. Schreib was dazu

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>