Sven Rautenberg: MySQL Performance

Beitrag lesen

Moin!

Grundsätzlich kann man sagen: Indizes beschleunigen das Lesen, verlangsamen aber das Schreiben von Daten.

Es ist daher gar nicht immer schlau, möglichst viele Indizes zu setzen.

Das ist richtig, aber es ist m.E. fast immer schlau bei geeignetem Füllfaktor viele Indexes zu setzen.

Nein, das eben gerade nicht. Einen Index zu füllen sorgt für Mehrarbeit beim Neuschreiben von Datensätzen (INSERT und UPDATE). Nicht umsonst wird als erheblich performancesteigernd angesehen, wenn man eine Tabelle neu importieren will, dass man zunächst KEINERLEI Index auf die Tabelle legt, dann die Daten hineinschreibt, und erst nachträglich die gewünschten Indices anlegen läßt. MySQL ist schneller, wenn das Generieren des Index einmal für die gesamte Tabelle erledigt wird, anstatt bei jedem Datensatz den Index neu zu befüllen und dabei ggf. auch neu zu sortieren.

Je mehr Indices die Tabelle hat, desto langsamer wird das Speichern. Deshalb sollte man nur die unbedingt notwendigen Indices setzen, nicht blind soviele, wie möglich.

Wenn es tatsächlich zu Performanceproblemen kommt, ist außerdem eine Analyse der Querys notwendig. Nicht jede Spalte eignet sich wirklich für einen Index. Wenn beispielsweise eine Spalte nur zwei oder drei mögliche Werte aufweisen kann (ein ENUM mit z.B. ja/nein, männlich/weiblich o.ä.), die sich anteilsmäßig ungefähr gleich auf die Datensätze verteilen, dann bringt ein Index auf dieser Spalte keinen Vorteil, weil ein SELECT auf dieser Spalte ja trotzdem noch die Hälfte der Datensätze ergibt. Ein Full Table Scan ist da vermutlich schneller.

Vollkommen blödsinnig ist aber, aufgrund von Performanceangst (die ja auch erst mal zu begründen wäre) suboptimale Datenbankstrukturen zu wählen.

Du meinst zum Beispiel eine Tabelle pro Frage. :)

Ganz genau - wobei die Performancefrage sich natürlich dann doch irgendwann stellt, wenn auf genau EINER Tabelle konkurrierende Schreib- und Lesezugriffe stattfinden sollen - und zwar gleich intensiv beides. Schreibzugriffe müssen die Tabelle für andere Schreibzugriffe sperren, damit sich nicht zwei INSERTs oder UPDATEs ins Gehege kommen. In dieser Zeit kann die Tabelle aber dann auch nicht gelesen werden. Wenn die Datenbank dann noch viel Zeit mit Indexgenerierung verbringt, entsteht irgendwann Stau.

Aber auch dagegen ist oftmals ein Kraut gewachsen. Beispielsweise könnte man die Schreib- und Lesevorgänge voneinander trennen. Eine Originaltabelle wird dauernd beschrieben, und manchmal komplett ausgelesen, um eine Kopie in eine Lesetabelle zu schieben, die dann immer nur gelesen wird. Nachteil: In der Lesetabelle sind die Daten nicht topaktuell. Vorteil: Schreiben und Lesen kommen sich nicht in die Quere.

Solche Lösungsansätze sucht man aber üblicherweise erst dann, wenn man tatsächlich ein Performanceproblem hat.

- Sven Rautenberg

--
"Love your nation - respect the others."