Die Leistung einer Datenbank ent­schei­det oft maß­geb­lich über die Ge­schwin­dig­keit und Sta­bi­li­tät von Web­an­wen­dun­gen. MariaDB und MySQL bieten zahl­rei­che Mög­lich­kei­ten zur Op­ti­mie­rung: Von Kon­fi­gu­ra­ti­on über Indizes bis hin zu Caching und Re­pli­ka­ti­on. Mit gezielten Maßnahmen lassen sich die Da­ten­bank­res­sour­cen ef­fi­zi­en­ter nutzen und die Ant­wort­zei­ten für Abfragen deutlich re­du­zie­ren.

Managed Database Services
Da­ten­ban­ken – Auf´s We­sent­li­che kon­zen­trie­ren
  • IONOS Cloud-Partner: Die Experten für Ihren Datenbank-Betrieb
  • Flexibel: Maß­ge­schnei­der­te Datenbank-Lösungen ganz auf Ihre Be­dürf­nis­se
  • Re­chen­zen­tren in Deutsch­land: Ihre Daten sind sicher

Wieso sollte man MariaDB und MySQL op­ti­mie­ren?

Die Op­ti­mie­rung von MariaDB und MySQL ist sinnvoll, weil un­op­ti­mier­te Da­ten­ban­ken schnell an ihre Grenzen stoßen. Eine schlechte Per­for­mance kann zu langen La­de­zei­ten, Timeouts oder sogar Sys­tem­aus­fäl­len führen.

Gerade bei großen Da­ten­men­gen oder vielen gleich­zei­ti­gen Zugriffen belastet jede in­ef­fi­zi­en­te Abfrage CPU und RAM. Auch das Speichern von red­un­dan­ten Daten oder fehlende Indizes wirken sich negativ auf die Ge­schwin­dig­keit aus. Eine op­ti­mier­te Datenbank reduziert die Sys­tem­last, ver­bes­sert die Ska­lier­bar­keit und sorgt dafür, dass An­wen­dun­gen auch unter hoher Last stabil laufen.

Wie kann man MySQL/MariaDB op­ti­mie­ren?

Es gibt viele Mög­lich­kei­ten, eine MariaDB- oder MySQL-Datenbank auf einem Linux-Server zu op­ti­mie­ren. Dazu gehören An­pas­sun­gen an der Kon­fi­gu­ra­ti­on, Index-Op­ti­mie­rung, Ver­bes­se­rung der Abfragen, Tuning von InnoDB und die Nutzung von Caching oder Re­pli­ka­ti­on. Im Folgenden werden die wich­tigs­ten Maßnahmen vor­ge­stellt.

Mög­lich­keit 1: Langsame Anfragen iden­ti­fi­zie­ren

Ein Teil des Prozesses zur Op­ti­mie­rung von MySQL/MariaDB ist die Über­prü­fung auf langsame oder in­ef­fi­zi­en­te Abfragen. Eine schlecht struk­tu­rier­te MySQL/MariaDB-Abfrage kann die gesamte Datenbank ver­lang­sa­men.

MySQL/MariaDB kann kon­fi­gu­riert werden, um jede Abfrage zu pro­to­kol­lie­ren, die länger als die an­ge­ge­be­ne Anzahl von Sekunden dauert. Auf diese Weise können Sie alle langsamen Anfragen verfolgen und bei Bedarf kor­ri­gie­ren.

Um die Pro­to­kol­lie­rung langsamer Abfragen zu ak­ti­vie­ren, melden Sie sich bei MySQL/MariaDB an:

mysql -u root -p

Geben Sie den folgenden Befehl ein, um die Pro­to­kol­lie­rung zu ak­ti­vie­ren:

SET GLOBAL slow_query_log = 'ON';

Der vor­ein­ge­stell­te Schwel­len­wert beträgt 10 Sekunden. Verwenden Sie den folgenden Befehl, um die Pro­to­kol­lie­rung für jede Abfrage zu ak­ti­vie­ren, die länger als 1 Sekunde dauert:

SET GLOBAL long_query_time = 1;

Abfragen, die länger als 1 Sekunde dauern, werden unter /var/lib/mysql/hostname-slow.log pro­to­kol­liert.

Auch Mo­ni­to­ring-Tools wie mysqltuner oder performance_schema können genutzt werden und liefern wertvolle Hinweise, um zu erkennen, welche Abfragen optimiert werden können.

Mög­lich­keit 2: InnoDB-Kon­fi­gu­ra­ti­on anpassen

Die Kon­fi­gu­ra­ti­on von MariaDB/MySQL ist eine der wir­kungs­volls­ten Methoden, um die Per­for­mance einer Datenbank nach­hal­tig zu ver­bes­sern. Viele Stan­dard­in­stal­la­tio­nen nutzen ge­ne­ri­sche Werte, die für kleinere Test­um­ge­bun­gen ausgelegt sind, aber nicht für pro­duk­ti­ve Systeme mit vielen Abfragen. Durch das gezielte Anpassen von InnoDB-Pa­ra­me­tern kann die Datenbank Res­sour­cen ef­fi­zi­en­ter nutzen.

Wichtige Parameter sind unter anderem:

  • innodb_flush_log_at_trx_commit: Diese Ein­stel­lung bietet einen er­heb­li­chen Kom­pro­miss zwischen Leistung und Zu­ver­läs­sig­keit. Stan­dard­mä­ßig steht der Wert auf 1, was bedeutet, dass jede Trans­ak­ti­on sofort auf die Fest­plat­te ge­schrie­ben wird. Das ga­ran­tiert maximale Si­cher­heit, kann jedoch die Per­for­mance bei hoher Trans­ak­ti­ons­last stark re­du­zie­ren. Ein Wert von 2 reduziert I/O-Ope­ra­tio­nen erheblich, während ein geringes Risiko von Da­ten­ver­lust bei einem Absturz besteht.
  • innodb_log_file_size: Die Größe der InnoDB-Log­da­tei­en hat direkten Einfluss auf die Ge­schwin­dig­keit von Schrei­b­ope­ra­tio­nen. Größere Logfiles bedeuten, dass mehr Trans­ak­tio­nen im Speicher gesammelt werden können, bevor sie auf die Fest­plat­te ge­schrie­ben werden.
  • innodb_file_per_table: Mit dieser Option wird für jede InnoDB-Tabelle eine eigene Ta­b­le­space-Datei erstellt. Das hat mehrere Vorteile: Es er­leich­tert das Ma­nage­ment großer Tabellen, reduziert Frag­men­tie­rung innerhalb des ge­mein­sa­men Ta­b­le­spaces und kann die Per­for­mance bei Backups ver­bes­sern.
  • innodb_buffer_pool_size: Dieser Wert sollte ty­pi­scher­wei­se 50–80 % des ver­füg­ba­ren RAMs ausmachen, um möglichst viele Daten und Indizes im Speicher zu halten.
  • innodb_flush_method: Diese Option legt fest, wie InnoDB Daten und Logs auf die Fest­plat­te schreibt. Setzen Sie diesen Wert auf O_DIRECT, um eine doppelte Pufferung der Daten zu vermeiden.

Um die InnoDB-Ein­stel­lun­gen zu ändern, öffnen Sie die Datei my.cnf zur Be­ar­bei­tung. Eine ex­em­pla­ri­sche Kon­fi­gu­ra­ti­on in my.cnf könnte dann bei­spiels­wei­se so aussehen:

[mysqld]
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 512M
innodb_file_per_table = 1
innodb_buffer_pool_size = 1G
innodb_flush_method = O_DIRECT

Starten Sie MariaDB/MySQL neu, damit die Än­de­run­gen wirksam werden.

Mög­lich­keit 3: Indizes anpassen

Indizes sind es­sen­zi­ell, um die Per­for­mance von MySQL- oder MariaDB-Abfragen zu ver­bes­sern. Statt jede Zeile einer Tabelle zu durch­su­chen, kann die Datenbank mithilfe des Index direkt zu den re­le­van­ten Einträgen springen.

Al­ler­dings gilt: Zu viele oder falsche Indizes können kon­tra­pro­duk­tiv sein. Jeder zu­sätz­li­che Index benötigt Spei­cher­platz. Daher ist es wichtig, nur die Spalten zu in­de­xie­ren, die tat­säch­lich häufig verwendet werden.

Ein einfaches Beispiel: An­ge­nom­men, wir haben eine Tabelle users und suchen oft nach der Spalte email. Dann kann ein Index die Abfragen erheblich be­schleu­ni­gen:

CREATE INDEX idx_user_email ON users(email);

Mit diesem Index werden Abfragen wie

SELECT * FROM users WHERE email='xyz@example.com';

deutlich schneller aus­ge­führt, weil die Datenbank nicht jede Zeile der Tabelle durch­su­chen muss, sondern direkt auf die passenden Einträge zugreift.

Zu­sätz­lich können kom­bi­nier­te Indizes sinnvoll sein, wenn mehrere Spalten zusammen häufig in Abfragen verwendet werden.

Re­gel­mä­ßig sollten auch nicht mehr benötigte oder selten genutzte Indizes entfernt werden, um Speicher zu sparen und die Schreib­per­for­mance zu ver­bes­sern. Im Beispiel wird der Index idx_old_column gelöscht:

DROP INDEX idx_old_column ON users;

Mög­lich­keit 4: Abfragen op­ti­mie­ren

Komplexe oder in­ef­fi­zi­en­te SQL-Abfragen können die Datenbank stark belasten und die Per­for­mance ver­schlech­tern, ins­be­son­de­re bei großen Tabellen. Um Abfragen zu op­ti­mie­ren, sollten Sie zunächst prüfen, wie die Datenbank die Abfrage ausführt. Dazu eignet sich der Befehl EXPLAIN.

EXPLAIN SELECT id, email FROM users WHERE status='active';

Mit EXPLAIN zeigt MySQL/MariaDB, welche Indizes verwendet werden, wie viele Zeilen gelesen werden müssen und in welcher Rei­hen­fol­ge Tabellen ver­ar­bei­tet werden. So können Sie erkennen, ob die Abfrage effizient ist oder ob zu­sätz­li­che Op­ti­mie­run­gen sinnvoll sind, z. B. das Hin­zu­fü­gen von Indizes oder das Anpassen von Joins.

Vermeiden Sie zudem Abfragen der Form SELECT *, da dabei viele Spalten geladen werden, die nicht benötigt werden. Statt­des­sen sollten Sie nur die Spalten abfragen, die wirklich gebraucht werden. Das reduziert die Menge an über­tra­ge­nen Daten und ver­bes­sert die Ge­schwin­dig­keit der Abfrage. Bei komplexen Joins lohnt es sich, die Be­din­gun­gen in der WHERE-Klausel so präzise wie möglich zu for­mu­lie­ren, um unnötige Scans der gesamten Tabelle zu ver­hin­dern.

Mög­lich­keit 5: Re­pli­ka­ti­on und Caching

Auch Re­pli­ka­ti­on, also das Verteilen der Last auf mehrere Server, sowie Caching, um die Anzahl der direkten Da­ten­bank­zu­grif­fe zu re­du­zie­ren, können dabei helfen, MariaDB/MySQL zu op­ti­mie­ren.

Bei der Re­pli­ka­ti­on wird in der Regel das so­ge­nann­te Master-Slave-Prinzip ein­ge­setzt: Der Master-Server ver­ar­bei­tet alle Schrei­b­ope­ra­tio­nen, während ein oder mehrere Slave-Server die Daten re­pli­zie­ren und Le­se­ab­fra­gen über­neh­men. So kann die Datenbank hohe Last ef­fi­zi­en­ter be­wäl­ti­gen, ohne dass der Master-Server über­las­tet wird. Kon­fi­gu­ra­ti­on und Ein­rich­tung der Re­pli­ka­ti­on erfordern zwar initial Aufwand, bringen aber gerade bei stark genutzten An­wen­dun­gen eine Ver­bes­se­rung der Per­for­mance.

Zu­sätz­lich kann auch Caching die Ant­wort­zei­ten deutlich ver­bes­sern. MySQL/MariaDB bietet dazu den Query Cache, der Er­geb­nis­se häufig wie­der­hol­ter Abfragen zwi­schen­spei­chert. Dadurch müssen dieselben Abfragen nicht erneut aus­ge­führt werden. Mit folgenden Ein­stel­lun­gen können Sie die Größe des Caches festlegen und den Query-Cache ak­ti­vie­ren:

SET GLOBAL query_cache_size = 64*1024*1024;
SET GLOBAL query_cache_type = 1;

Für moderne An­wen­dun­gen ist es außerdem sinnvoll, externe Caching-Lösungen wie Redis zu nutzen, die noch schneller auf häufig benötigte Daten zugreifen können.

Mög­lich­keit 6: Par­ti­tio­nie­rung von Tabellen

Bei sehr großen Tabellen kann die Ver­ar­bei­tung von Abfragen länger dauern, weil die Datenbank jede Zeile durch­su­chen muss. Mit Par­ti­tio­nie­rung lassen sich Tabellen in kleinere, logisch getrennte Teile un­ter­tei­len, z. B. nach Datum, ID-Bereich oder anderen Kriterien. Jede Partition wird intern wie eine separate Tabelle behandelt, sodass Abfragen, die nur bestimmte Par­ti­tio­nen betreffen, deutlich schneller aus­ge­führt werden können.

Ein Beispiel für eine Par­ti­tio­nie­rung nach Jahr bei einer Bestell-Tabelle könnte so aussehen:

CREATE TABLE orders (
id INT,
order_date DATE,
amount DECIMAL(10,2)
)
PARTITION BY RANGE (YEAR(order_date)) (
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025)
);

In diesem Fall werden alle Be­stel­lun­gen aus 2023 in der Partition p2023 und alle Be­stel­lun­gen aus 2024 in p2024 abgelegt.

Mög­lich­keit 7: Ver­bin­dungs­poo­ling nutzen

Jede neue Ver­bin­dung zu MySQL/MariaDB benötigt Zeit und Res­sour­cen. Wenn Ihre Anwendung bei jeder Anfrage eine Ver­bin­dung auf- und wieder abbaut, entsteht dadurch eine unnötige Last auf dem Server. Das so­ge­nann­te Ver­bin­dungs­poo­ling kann genutzt werden, um MariaDB und MySQL zu op­ti­mie­ren, und löst dieses Problem, indem eine bestimmte Anzahl von Da­ten­bank­ver­bin­dun­gen dauerhaft geöffnet bleibt. An­wen­dun­gen greifen dann immer wieder auf diese be­stehen­den Ver­bin­dun­gen zurück, anstatt neue auf­zu­bau­en.

Ein Beispiel in PHP mit mysqli sieht so aus:

$mysqli = new mysqli('localhost', 'user', 'password', 'db');
$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
php

Anstatt für jeden Request eine komplett neue Ver­bin­dung zu öffnen, nutzt der Pool die bereits be­stehen­den Ver­bin­dun­gen. Das führt zu schnel­le­ren Re­ak­ti­ons­zei­ten und entlastet gleich­zei­tig den Da­ten­bank­ser­ver.

Zum Hauptmenü