mysql und Caching

mysql und Caching

Diesen Beitrag schrieb ich 13 Jahre und 9 Monate zuvor; die nachfolgenden Ausführungen müssen heute weder genau so nach wie vor funktionieren, noch meiner heutigen Meinung entsprechen. Behalte das beim Lesen (und vor allem: beim Nachmachen!) bitte stets im Hinterkopf.

Geschätzte Lesezeit: 2 Minuten

Wozu eigentlich den MySQL-Query-Cache aktivieren? Nun – er speichert zweierlei, nämlich

  • zum einen die SELECT-Anweisung und
  • zum anderen das zu der Anweisung gehörige Ergebnis, das dem Client übermittelt wurde.

Wird hernach die selbe Anweisung erneut empfangen, so wird das SELECT-Statement nicht erneut ausgeführt, sondern das Ergebnis aus dem Cache gegriffen und übermittelt. Dies spart natürlich Ressourcen – was sich beispielsweise bei gut besuchten Webseiten doch deutlich bemerkbar macht. Und wer nun skeptisch ist, der sei beruhigt: der MySQL-Query-Cache liefert keine veralteten Daten zurück – werden Tabellen modifiziert, wird auch der Cache synchronisiert. Doch wie prüfe ich nun, ob das Caching auf meinem Server aktiviert ist – beziehungsweise wie aktiviere ich es? Melde dich per mysql -u root -p an deinem MySQL-Server an und schau nach:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 634
Server version: 5.0.83-0ubuntu3 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like '%cache%';
+------------------------------+----------------------+
| Variable_name                | Value                |
+------------------------------+----------------------+
| binlog_cache_size            | 32768                | 
| have_query_cache             | YES                  | 
| key_cache_age_threshold      | 300                  | 
| key_cache_block_size         | 1024                 | 
| key_cache_division_limit     | 100                  | 
| max_binlog_cache_size        | 18446744073709547520 | 
| ndb_cache_check_time         | 0                    | 
| query_cache_limit            | 1048576              |
| query_cache_min_res_unit     | 4096                 | 
| query_cache_size             | 0                    |
| query_cache_type             | ON                   |
| query_cache_wlock_invalidate | OFF                  | 
| table_cache                  | 64                   | 
| thread_cache_size            | 0                    | 
+------------------------------+----------------------+
14 rows in set (0.00 sec)

have_query_cache gibt hierbei an, ob die Caching-Funktionalität prinzipiell vorhanden ist; ein YES sagt jedoch an dieser Stelle nur aus, dass sie da ist – nicht aber, dass sie auch aktiv ist! query_cache_limit gibt die maximale Größe einer Anfrage an, die im Cache vorgehalten werden kann; der Default hierfür ist 1MB (1048576). Daneben bezeichnet query_cache_size die Größe des Speichers, der insgesamt für zwischengespeicherte Anfragen zur Verfügung steht. Der Default hierfür lautet 0, und das ist gleichbedeutend mit „abgeschaltetem Caching“. Um den Wert nun (global) auf 256MB zu erhöhen und das Caching somit anzuschalten, kann man beispielsweise wie folgt vorgehen:

$ echo "256*1024*1024" | bc
268435456
mysql> set global query_cache_size = 268435456;
Query OK, 0 rows affected (0.00 sec)

Das setzt den Wert im laufenden Betrieb des Servers auf den angegebenen Wert; bereits bestehende Verbindungen (Sessions) sind hiervon aber gegebenenfalls nicht betroffen! Wird bei SHOW VARIABLES weder GLOBAL noch SESSION angeben, gibt MySQL immer den SESSION-Wert zurück – das ist ebenfalls wichtig zu wissen. Nun kann man den Cache manuell initialisieren, was eine Defragmentierung des Caches bewirkt und auch zur Optimierung eingesetzt werden kann (hierbei werden keine hinterlegten Abfragen gelöscht):

mysql> FLUSH QUERY CACHE;

Ebenso lassen sich alle gespeicherten Ergebnisse manuell aus dem Query-Cache löschen:

mysql> RESET QUERY CACHE;

Natürlich lassen sich die Einstellungen auch in der my.cnf hinterlegen, hier dann (ab MySQL-Version >= 5.0) beispielsweise in der Form

query_cache_limit       = 1M
query_cache_size        = 256M
query_cache_type        = 1

Um Informationen über den aktuellen Status des Caches zu erhalten, kann man beispielsweise folgendermaßen vorgehen:

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| Qcache_free_blocks      | 3559      | 
| Qcache_free_memory      | 242407856 | 
| Qcache_hits             | 1560460   | 
| Qcache_inserts          | 46485     | 
| Qcache_lowmem_prunes    | 0         | 
| Qcache_not_cached       | 31029     | 
| Qcache_queries_in_cache | 13806     | 
| Qcache_total_blocks     | 31344     | 
+-------------------------+-----------+
8 rows in set (0.00 sec)

Wichtig: bei einem Restart des Servers (=Prozesses) gehen die zwischengespeicherten Daten (!!! die im RAM vorgehalten werden !!!) natürlich verloren. Insofern sollte man darauf achten, nicht jeglicher Mini-Änderung direkt ein /etc/init.d/mysqld restart folgen zu lassen! Die meisten Settings lassen sich, wie man sieht, mühelos im laufenden Betrieb einstellen.

Alle Bilder dieser Seite: © Marianne Spiller – Alle Rechte vorbehalten
Hintergrundbild: Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten

Eure Gedanken zu „mysql und Caching“

Ich freue mich über jeden Kommentar, es sei denn, er ist blöd. Deshalb behalte ich mir auch vor, die richtig blöden kurzerhand wieder zu löschen. Die Kommentarfunktion ist über GitHub realisiert, weshalb ihr euch zunächst dort einloggen und „utterances“ bestätigen müsst. Die Kommentare selbst werden im Issue-Tracker und mit dem Label „✨💬✨ comment“ erfasst – jeder Blogartikel ist ein eigenes Issue. Über GitHub könnt ihr eure Kommentare somit jederzeit bearbeiten oder löschen.