MySQL Performance

MySQL Community Edition hat brauchbare Default Einstellungen, aber die Konfiguration muß auf jeden Fall an die Bedürfnisse angepaßt werden.


Analyse

Performance Schema

Das Server Feature Performance Schema (seit MySQL 5.5) muß einkonfiguriert sein, damit der Server entsprechende Daten mitloggt (in Datenbanktabellen schreibt). In der MySQL Workbench kann man Über Server - Performance Server Setup den Detailgrad des Loggings definieren.

Mit der MySQL Workbench können die Ergebnisse recht komfortabel ausgewertet werden.

ACHTUNG: die Bereitstellung der Performance-Daten kostet auf jeden Fall Performance auf dem Server!!!

MySQL Workbench

Dieses kostenlose Tool ist schon sehr praktisch, wenn man auf der Suche nach Bottlenecks ist.

MySQL Enterprise Manager

MySQLTuner-perl

Logging

In der Softwareentwicklung verwendet man häufig Prepared Queries, weil deren Execution Plan nur ein einziges mal berechnet werden muß und dann unabhängig von den Parameter-Bindings genutzt werden können. Explain Plan ist eine recht teure Operation und deshalb macht dieses Vorgehen Sinn.

Nachteil dieses Ansatzes ist allerdings, daß Query und Parameter getrennt sind und häufig auch getrennt geloggt werden (z. B. EclipseLink mit eclipselink.logging.level.sql und eclipselink.logging.parameters).

Konfiguriert man das Logging im MySQL Server entsprechend

general_log=0
general_log_file=/var/lib/mysql/general-log-file.log

, dann erhält man im Log vollständige Queries, die man direkt in der MySQL Workbench ausführen kann, um den Explain Plan zu untersuchen.

Slow-Query Log

Hierüber werden langlaufende Queries in eine Datei geloggt:

slow_query_log=0
slow_query_log_file=/var/lib/mysql/slow-query.log
long_query_time=2

Der letzte Parameter bestimmt welche Ausführungszeit als slow eingestuft wird.

Sehr praktisch!!!


Tips

Dedicated DB Server

Am besten verwendet man einen dedizierten DB-Server, der sich die Ressourcen nicht mit anderen Komponenten (z. B. Application-Server) teilen muß. Der Vorteil darin, daß das Tuning (über entsprechende Konfigurationsparameter) deutlich einfacher ist.

Konfiguration

InnoDB Buffer Pool

Hierbei handelt es sich um den wichtigsten Konfigurationsparameter. Der Schalter innodb_buffer_pool_size bestimmt wieviel RAM MySQL für Caching und Indizes verwenden darf. Bei einem MySQL dedicated Rechner sollte man 70-80% des verfügbaren RAM verwenden.

Query Cache Size

Dieser Cache macht Sinn, wenn man immer wieder die gleichen Queries absetzt. Ist das nicht der Fall, dann macht es keinen Sinn. Ist der Wert zu hoch, dann hat das nachteilige Ausweirkungen auf die Performance, weil der Cache gelockt werden muß, um ihn zu aktualisieren, d. h. die Threads der anderen Queries werden auch blockiert. Ein Wert zwischen 64 und 256 MB sollte i. a. ausreichend sein.

Max Connections

Jede Connection (die beispielsweise über die Konfiguration des Application Server Connection Pool aufgebaut wird) benötigt - auch wenn sie nicht genutzt wird - Speicher auf dem MySQL Server.

OS Swappiness

Defaultmäßig fangen Betriebssysteme bei einer bestimmten RAM-Nutzung (Linux 60% - sysctl vm.swappiness) mit swappen an ... für einen Datenbankserver ist Swapping ganz schlecht - noch schlechter ist es, wenn fachfremde (Betriebssystem) darüber entscheidet welche Teile auf die Festplatte ausgelagert werden. Eine Datenbank ist - im besten Fall - ein hochoptimiertes System, das an der Leistungsgrenze läuft ... da kann man sich keine generischen Auslagerungsstrategien eines Betriebssystems leisten.

DB Filesystem I/O

Eine Datenbank sollte nach möglichkeit die meisten Sachen im Hauptspeicher machen und optimal die Festplatte einbinden (lesen/schreiben). Dafür gibt es entsprechende Konfigurationsparameter, die an die jeweilige Anwendung anzupassen sind - denn der DBA bzw. die Entwickler dieser Anwendnung wissen am besten wie sich die Anwendung verhält und welche Einstellungen dafür am besten geeignet sind.

Richtiges Filesystem verwenden

Das richtige Filesystem ist von der verwendeten Storage Engine abhängig ... für MySQL mit InnoDB Storage Engine werden die Filesysteme XFS, Ext4 und Btrfs empfohlen.

analyze table

Die Ermittlung des optimalen Explain Plan hängt vom Inhalt der Tabellen ab. Das liegt daran, daß häufig - aufgrund von Indexen, die ähnlich sind - verschiedene Zugriffspfade existieren (neben einem FULL TABLE SCAN). Ein analyze table hilft dem Optimizer bessere Execution Plans zu ermitteln. Deshalb sollte man dies auch regelmäßig tun.

Unter Oracle kennt man das als GATHER STATS JOB

Am besten verwendet man ein Script, das alle Tabellen einer Datenbank analyisiert:

mysqlcheck --analyze --databases myDatabase --user=root --password=pwd

Häufig ist diese Analyse auch relativ schnell durch (hängt natürlich von der Datenbankgröße ab).

  • FRAGE: blockiert es???

Per show index myTable kann man auch die Effizienz der Indizes erfahren (in MySQL Workbench sieht an das über den Table Inspector). Eine Kardinalität von 0 deutet auf eine schlechte Effizienz hin ... vielleicht verschafft ein analyze table hier Abhilfe.

optimize table

Im Gegensatz zum analyze table greift optimize table in die Speicherorganisation der Datenbank ein (die Fragmentierung wird reduziert).

Selektivität

Das Ziel des Optimizers ist es, möglichst schnell eine Reduktion der zu berücksichtigenden Datenmenge zu erreichen. Das schafft man, indem die WHERE-clauses ausgewertet werden mit den Indizes, die das erreichen.

Kardinalität

Die Kardinalität beschreibt wieviele verschiedene Werte ein Index hat. Beispiele:

  • bei einem Index auf sex könnte das beispielsweise 2 sein
  • bei einem Index auf (age, sex) könnten das - angenommen die Personen gehen von 0 Jahre bis 100 Jahre und sind Männer und Frauen - 200 sein

Die Kardinalität in Relation zur Anzahl der Zeilen spiegelt die Selektivität des Index wieder.

Ein Index mit niedriger Kardinalität (sex) kann aber dennoch gute Dienste leisten. Wenn die Verteilung in der Tabelle bei

  • male: 99
  • female: 1

liegt, dann ist ein select * from person where sex = 'female' extrem schnell.

Zusammengesetzte Indizes

Ein Index sollte so gewählt sein, daß die Spalten mit der höchsten Reduktion weit vorne stehen. Ein Beispiel:

  • BESSER: CREATE INDEX idx ON person (age, sex)
  • SCHLECHTER: CREATE INDEX idx ON person (sex, age)

ACHTUNG: besser oder schlechter hängt von der Datenverteilung ab. Wenn ich eine Normalverteilung habe, gelten die Aussagen. Habe ich allerdings nur Personen im Alter von 13 Jahren, dann wäre (sex, age) besser. DESHALB ist es bei der Performanceoptimierung wichtig, mit realistischen Daten zu arbeiten, die möglichst die gleiche Verteilung aufweisen wie in Live-Betrieb.

Fragmentierung

Partitionierung


FAQ

count(foo) ist teuer

results matching ""

    No results matching ""