Wenn das Unix-Tool top
oder der Windows
Task Manager zeigt, dass die CPU-Last unter 70% liegt, läuft
Ihre Arbeit wahrscheinlich festplattengebunden ab. Vielleicht
committen Sie zu oft Transaktionen oder Ihr Bufferpool ist zu
klein. Diesen zu vergrößern könnte helfen, aber stellen sie
ihn nicht auf 80% des physikalischen Speichers oder gar mehr
ein.
Verpacken Sie mehrere Modifikationen in eine einzige
Transaktion. InnoDB
muss bei jedem Committ
einer Transaktion, die etwas an der Datenbank änderte, die
Logs auf die Festplatte zurückschreiben. Da diese meist mit
einer Geschwindigkeit von höchstens 167 Umdrehungen/Sekunde
rotiert, ist diese 167tel Sekunde auch für Committs die
Obergrenze, wenn die Festplatte es nicht schafft, das
Betriebssystem zu „überlisten“.
Wenn Sie es sich leisten können, im Falle eines Absturzes
einige Ihrer zuletzt committeten Transaktionen zu verlieren,
können Sie den
innodb_flush_log_at_trx_commit
-Parameter
auf 0 setzen. InnoDB
versucht ohnehin, das
Log einmal pro Sekunde auf die Platte zu schreiben, auch wenn
dies nicht immer klappt.
Machen Sie Ihre Logdateien groß, vielleicht genauso groß wie
den Bufferpool. Wenn InnoDB
die Logdateien
vollgeschrieben hat, muss es den neuen Inhalt des Bufferpools
in einem Checkpoint auf die Platte schreiben. Kleine
Logdateien verursachen viele überflüssige Schreibvorgänge
auf der Festplatte. Der Nachteil großer Logdateien ist die
längere Recovery-Zeit.
Machen Sie auch den Logpuffer recht groß (etwa 8MB).
Verwenden Sie zur Speicherung von Strings variabler Länge
oder wenn die Spalte NULL
-Werte enthalten
kann, VARCHAR
statt CHAR
als Datentyp. Eine
CHAR(
-Spalte
speichert immer N
)N
Zeichen, selbst
wenn der String kürzer oder sein Wert NULL
ist. Kleinere Tabellen passen besser in den Bufferpool und
reduzieren die Schreibvorgänge auf der Festplatte.
Wenn Sie die Standardeinstellung
row_format=compact
für das Datensatzformat
von MySQL 5.1 Zeichensätze variabler Länge wie
etwa utf8
oder sjis
verwenden, belegt
CHAR(
eine
variable Menge Speicherplatz, allerdings mindestens
N
)N
Bytes.
In manchen Versionen von GNU/Linux und Unix geht es
erstaunlich langsam, Daten mit dem Unix-Aufruf
fsync()
(den InnoDB
standardmäßig verwendet) und anderen, ähnlichen Methoden
auf die Platte zu schreiben. Wenn Sie mit der Schreibleistung
Ihrer Datenbank unzufrieden sind, setzen Sie den
innodb_flush_method
-Parameter auf
O_DSYNC
. Zwar scheint
O_DSYNC
auf den meisten Systemen die
langsamere Variante zu sein, aber vielleicht ist es gerade auf
Ihrem schneller.
Wenn Sie InnoDB
auf Solaris 10 for x86_64
(AMD Opteron) einsetzen, ist es wichtig, alle zum Speichern
von InnoDB
-Dateien verwendeten Dateisysteme
mit der forcedirectio
-Option zu mounten
(die standardmäßig auf Solaris 10/x86_64
nicht benutzt wird). Wenn Sie dies nicht
tun, läuft InnoDB
auf dieser Plattform
sehr viel langsamer und hat eine geringere Performance.
Wenn Sie InnoDB
mit einem großen
innodb_buffer_pool_size
-Wert auf Solaris
2.6 und höher auf einer beliebigen Plattform
(sparc/x86/x64/amd64) einsetzen, können Sie die Performance
massiv steigern, indem Sie die
InnoDB
-Daten- und -Logdateien auf Raw
Devices oder einem separaten UFS-Dateisystem mit Direkt-E/A
speichern (und zwar mit der Mount-Option
forcedirectio
, siehe
mount_ufs(1M)
). Wer das Veritas-Dateisystem
VxFS hat, sollte die Mount-Option
convosync=direct
setzen.
Andere MySQL-Datendateien, wie etwa die für
MyISAM
-Tabellen, sollten nicht in einem
Dateisystem mit Direkt-E/A abgelegt werden. Executables oder
Bibliotheken dürfen niemals in einem
Dateisystem mit Direkt-E/A abgelegt werden
Beim Datenimport in InnoDB
müssen Sie
darauf achten, dass MySQL nicht im Autocommit-Modus läuft, da
dieser bei jedem Insert die Logs auf die Festplatte
zurückschreibt. Um während der Import-Operation Autocommit
auszuschalten, schließen Sie die Operation in SET
AUTOCOMMIT
und COMMIT
-Anweisungen
ein:
SET AUTOCOMMIT=0;
... SQL import statements ...
COMMIT;
Mit der mysqldump-Option
--opt
erhalten Sie Dump-Dateien, die sich in
eine InnoDB
-Tabelle ganz schnell
importieren lassen, selbst ohne den Import in die Anweisungen
SET AUTOCOMMIT
und
COMMIT
zu verpacken.
Hüten Sie sich vor umfangreichen Rollbacks von
Masseneinfügeoperationen: InnoDB
benutzt
den Insert-Puffer zwar bei den Einfügungen, um
Schreibvorgänge zu minimieren, aber nicht bei den
zugehörigen Rollbacks. Ein festplattengebundener Rollback
kann 30-mal so lange wie der zugehörige Insert brauchen.
Dabei hilft es auch nichts, den Datenbankprozess anzuhalten,
da der Rollback beim Hochfahren des Servers wieder von vorne
beginnt. Die einzige Möglichkeit, einen außer Kontrolle
geratenen Rollback aufzuhalten, besteht darin, den Bufferpool
so groß anzusetzen, dass der Rollback CPU-gebunden und somit
schneller läuft, oder eine spezielle Prozedur einzusetzen.
Siehe Abschnitt 14.2.8.1, „Erzwingen einer InnoDB
-Wiederherstellung (Recovery)“.
Hüten Sie sich auch vor anderen umfangreichen
festplattengebundenen Operationen. Verwenden Sie zum Leeren
einer Tabelle DROP TABLE
und
CREATE TABLE
, aber nicht DELETE
FROM
.
tbl_name
Mit dem mehrzeiligen INSERT
können Sie den
Kommunikationsaufwand zwischen Client und Server minimieren,
wenn Sie viele Zeilen einfügen müssen:
INSERT INTO yourtable VALUES (1,2), (5,5), ...;
Dieser Tipp gilt übrigens für Einfügungen in alle
möglichen Tabellen, nicht nur in
InnoDB
-Tabellen.
Wenn Sie UNIQUE
-Constraints auf
Sekundärschlüsseln haben, können Sie Tabellenimporte
beschleunigen, indem Sie die Eindeutigkeitsprüfung während
der Import-Session vorübergehend abschalten:
SET UNIQUE_CHECKS=0;
... import operation ...
SET UNIQUE_CHECKS=1;
Bei großen Tabellen spart dies eine Menge Plattenzugriffe, da
InnoDB
seine Insert-Puffer dazu benutzen
kann, Sekundärindexeinträge als Batch zu verarbeiten.
Wenn Ihre Tabellen FOREIGN KEY
-Constraints
haben, können Sie Tabellenimporte beschleunigen, indem Sie
für die Dauer der Import-Session die Fremschlüsselprüfungen
abschalten:
SET FOREIGN_KEY_CHECKS=0;
... import operation ...
SET FOREIGN_KEY_CHECKS=1;
Bei großen Tabellen spart dies eine Menge Plattenzugriffe.
Wenn Sie oft wiederkehrende Anfragen auf Tabellen haben, die sich nur selten ändern, nutzen Sie den Query-Cache:
[mysqld] query_cache_type = ON query_cache_size = 10M
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.