Wie Du die Größe einer Datenbank und Tabelle in MySQL (SQL) ermittelst

Datenbanken wachsen leise. Irgendwann dauert ein Backup zu lange, ein Plattenalarm geht los, oder ein Hoster will Geld für mehr Speicher — und die erste Frage ist immer dieselbe: was ist hier eigentlich groß? Dafür brauchst Du kein Werkzeug. MySQL und MariaDB führen die Zahlen in information_schema, und drei Abfragen holen sie heraus.

Alle Datenbanken auf einen Blick

Diese Abfrage als Benutzer mit Zugriff auf den Server ausführen, zum Beispiel root. Sie listet jede Datenbank mit ihrer Größe in Megabyte, die größte zuerst.

SELECT table_schema AS db,
       ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS groesse_mb
FROM information_schema.tables
GROUP BY table_schema
ORDER BY groesse_mb DESC;

data_length sind die Daten, index_length die Indizes. Beides zu zählen ist das Praxisrelevante: bei einer schreiblastigen Tabelle können die Indizes größer sein als die Daten selbst.

Eine einzelne Datenbank

Wenn Du nur Zugriff auf Deine eigene Datenbank hast, nenne sie direkt. deine_datenbank ersetzen.

SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS groesse_mb
FROM information_schema.tables
WHERE table_schema = 'deine_datenbank';

Jede Tabelle einer Datenbank

Das ist die Abfrage, die die eigentliche Frage beantwortet — welche Tabelle das Problem ist.

SELECT table_name AS tabelle,
       engine,
       table_rows AS zeilen_ca,
       ROUND(data_length / 1024 / 1024, 2) AS daten_mb,
       ROUND(index_length / 1024 / 1024, 2) AS index_mb,
       ROUND((data_length + index_length) / 1024 / 1024, 2) AS gesamt_mb,
       ROUND(data_free / 1024 / 1024, 2) AS frei_mb
FROM information_schema.tables
WHERE table_schema = 'deine_datenbank'
ORDER BY data_length + index_length DESC;

Zwei Spalten lohnen genaues Lesen:

  • frei_mb (data_free) ist Platz innerhalb der Tabellendatei, der nicht mehr benutzt wird. Ein großer Wert heißt meistens, dass viele Zeilen gelöscht wurden. Die Datei behält ihre Größe, bis die Tabelle neu aufgebaut wird.
  • zeilen_ca (table_rows) ist bei InnoDB ein Schätzwert, keine Zählung. Nimm den Wert als Größenordnung.

Direkt aus der Shell

Für einen Cronjob oder einen schnellen Blick über SSH brauchst Du keinen SQL-Client. Der Schalter -e führt eine Anweisung aus und gibt das Ergebnis als Tabelle aus.

mysql -u root -p -e "SELECT table_schema AS db, \
  ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS groesse_mb \
  FROM information_schema.tables GROUP BY table_schema ORDER BY groesse_mb DESC;"

--batch ergänzt für eine Ausgabe mit Tabulatoren, die ein anderes Skript lesen kann, oder --vertical, wenn die Zeilen für das Terminal zu breit sind.

Warum die Zahl nie genau zur Platte passt

Eine Datenbank ist mehr als ihre Tabellen. du -sh /var/lib/mysql zeigt fast immer mehr an als die Abfragen oben, weil im Datenverzeichnis auch das Redo-Log, der Undo-Tablespace, die Binary Logs und temporäre Dateien liegen. Besonders die Binary Logs können größer werden als die Daten — wenn das Dein Fall ist, begrenze ihre Lebensdauer.

Die andere Richtung gibt es auch: direkt nach einem großen Löschvorgang melden die Abfragen noch die alte Größe, weil InnoDB seine Statistik träge auffrischt. ANALYZE TABLE meine_tabelle; aktualisiert sie, und OPTIMIZE TABLE meine_tabelle; baut die Tabelle wirklich neu auf und gibt den freien Platz an das Dateisystem zurück.

Eine kurze Prüfung, die sich auszahlt

Setz die Abfrage pro Tabelle auf eine monatliche Erinnerung. Wachstum, das Du kommen siehst, ist eine Planungsaufgabe. Wachstum, das Du bemerkst, wenn um drei Uhr nachts das Backup scheitert, ist ein Vorfall.

Häufige Fragen

Warum ist die gemeldete Größe kleiner als die Dateien auf der Platte?

Bei InnoDB sind die Zahlen in information_schema Schätzwerte der Speicher-Engine, und sie lassen den gemeinsamen Tablespace, das Redo-Log, die Binary Logs und temporäre Dateien außen vor. Eine Tabelle, die viele Zeilen verloren hat, behält außerdem ihre Dateigröße, bis sie neu aufgebaut wird; der freigebbare Teil steht in data_free.

Funktionieren die Abfragen auch mit MariaDB?

Ja. information_schema.tables hat in MySQL 5.7, MySQL 8, MariaDB und Percona Server dieselben Spalten, alle drei Abfragen laufen unverändert.

Warum sieht die Zeilenzahl falsch aus?

table_rows ist bei InnoDB ein Schätzwert aus der Engine-Statistik und kann deutlich abweichen. Für die genaue Zahl SELECT COUNT(*) nehmen, für frische Statistik ANALYZE TABLE.

Wie gebe ich den Platz nach dem Löschen wirklich frei?

Mit OPTIMIZE TABLE meine_tabelle die Tabelle neu aufbauen (InnoDB macht daraus einen Neuaufbau plus ANALYZE). Das braucht freien Plattenplatz in etwa der Größe der Tabelle und blockiert auf älteren Versionen Schreibzugriffe — also in ein Wartungsfenster legen.

Fragen zu diesem Thema?

Wir unterstützen Sie bei SEO, KI-Einführung und E-Commerce.

Projekt besprechen →