Der SQL-Abfrage-Cache
Diese Seite richtet sich an Datenbankadministratoren, die wissen möchten, ob der SQL-Abfrage-Cache ihrer Website hilft und was
er für Schreibzugriffe bedeutet, die sie selbst vornehmen. Der Cache behält die Zeilen, die ein SELECT zurückgegeben hat, und
beantwortet dieselbe Anweisung erneut, bis ein Schreibzugriff auf eine ihrer Tabellen das Ergebnis veralten lässt. Er ist
standardmäßig aus. Er funktioniert mit den Treibern für MySQL, MariaDB, PostgreSQL, SQLite und Oracle; der MongoDB-Treiber
verwendet ihn nicht. Quelle: Der SQL-Abfrage-Cache und settings/querycache.ini.
Inhalt
- Die Einstellungen
- Was nie gecacht wird
- Wie Schreibzugriffe ungültig machen
- Schreibzugriffe außerhalb von Exponential
- Ihn einschalten
- Was normal ist, worauf Sie achten
- Checkliste
Die Einstellungen
settings/querycache.ini [QueryCacheSettings], überschrieben in settings/override/querycache.ini.append.php:
| Schlüssel | Standard | Bedeutung |
|---|---|---|
Mode | off | off: nichts wird behalten. request: ein identisches SELECT wird in einer Anfrage nicht zweimal ausgeführt. shared: Ergebnisse werden auch über Anfragen hinweg behalten |
Storage | auto | Wo shared Ergebnisse hält: auto (APCu, wo der Prozess es hat, sonst Dateien), apcu oder file (var/<site>/cache/querycache/entries/, geteilt von jedem Webserver, der var/ einhängt) |
ApcuReserve | 25 | Prozent von APCu, die frei bleiben müssen; darunter werden Ergebnisse nur für die Anfrage behalten |
MaxAge | 300 | Längste Lebensdauer eines Ergebnisses in Sekunden, die Grenze für einen Schreibzugriff, den der Cache nicht sehen kann |
MaxRows | 5000 | Ergebnisse mit mehr Zeilen werden nicht behalten |
ExcludeTables[] | ezsession, ezpending_actions, ezcollab_notification_rule | Tabellen, deren SELECTs nie gecacht werden |
[DebugSettings] Report=enabled fügt die Zähler des Cache der Debug-Ausgabe hinzu.
Was nie gecacht wird
- Lesezugriffe innerhalb einer Transaktion;
- Anweisungen, deren Tabellen sich nicht alle aus dem Text lesen lassen: eine Unterabfrage, ein Hinweis oder
PARTITIONinFROM, ein geklammerter Join, ein Kommentar, ein Anführungszeichen ohne Partner oder in einem Namen in Anführungszeichen, die Literaleq''von Oracle sowieE''und Dollar-Quoting von PostgreSQL, alles, was kein einfachesSELECTist. JedesSELECTvonUNION,MINUS,INTERSECTundEXCEPTwird gelesen. Ob ein Backslash maskiert, hängt vom Treiber ab: in den Literalen von MySQL ja, in denen von PostgreSQL (mitstandard_conforming_stringsan, der Voreinstellung; der Treiber liest die Einstellung aus der Verbindung), SQLite und Oracle nicht; - Anweisungen, deren Ergebnis keine Funktion ihrer Tabellen ist:
NOW(),RAND(),UUID(),LAST_INSERT_ID(), Sperren (FOR UPDATE), Variablen,SQL_NO_CACHE; von PostgreSQLclock_timestamp(),txid_current(), die Funktionenpg_*()undFOR NO KEY UPDATE; von SQLitechanges(),last_insert_rowid()unddatetime('now'); - Lesezugriffe auf temporäre Tabellen;
- Ergebnisse mit mehr als
MaxRowsZeilen und Lesezugriffe aufExcludeTables.
Auf Oracle außerdem Anweisungen, die eine Sequenz, die Uhr, SYS_GUID, SYS_CONTEXT, DBMS_RANDOM oder den Katalog lesen.
Wie Schreibzugriffe ungültig machen
INSERT, REPLACE, UPDATE, DELETE, TRUNCATE, CREATE/ALTER/DROP TABLE, Indexänderungen und RENAME TABLE
markieren die Tabellen, die sie nennen, als beschrieben. Ein Schreibzugriff, dessen Tabellen sich nicht lesen lassen, markiert
alles als veraltet. Innerhalb einer Transaktion werden die Tabellen beim äußersten COMMIT markiert; bei ROLLBACK wird nichts
markiert. Andere Prozesse (Skripte, der Admin-Host, Velocity) sehen die Änderung über eine gemeinsame Zustandsdatei in
var/<site>/cache/querycache/.
Die Datei wird unter einer Sperre auf state.lock geschrieben, die für jeden Benutzer beschreibbar sein muss, unter dem die
Site läuft (FPM, Velocity, Cron); auf NFS braucht sie NFSv4 oder lockd. Ein Schreibzugriff, der die Sperre nicht nehmen
kann, markiert alle Ergebnisse als veraltet, und Setup > Systeminformationen meldet das in Rot. TRUNCATE ... CASCADE
und DROP ... CASCADE von PostgreSQL erreichen Tabellen, die die Anweisung nicht nennt, daher markieren sie ebenfalls
alles als veraltet. Das Cache-Verzeichnis zu löschen ist sicher: Ergebnisse, die unter der gelöschten Zustandsdatei
gehalten wurden, werden nie wieder geantwortet.
Schreibzugriffe außerhalb von Exponential
Der Cache kann einen Schreibzugriff mit einem SQL-Client, ein mysql < dump.sql, eine Wiederherstellung oder ein anderes
Programm nicht sehen. Ergebnisse bleiben bis zu MaxAge Sekunden gültig. Leeren Sie ihn nach jedem solchen Schreibzugriff und
nach jeder Wiederherstellung:
php bin/php/ezcache.php --clear-id=querycache --allow-root-useroder unter Setup > Caches. --clear-all und die Tags content und ini schließen ihn ein.
Ihn einschalten
- Prüfen Sie APCu: Setup > Systeminformationen, Abschnitt PHP, oder
php -m | grep apcu. - Setzen Sie
Mode=requestinsettings/override/querycache.ini.append.php; leeren Sie den INI-Cache, laden Sie PHP-FPM neu, starten Sie Velocity neu. Surfen Sie einen Tag lang. - Setzen Sie
Mode=sharedauf dieselbe Weise. Beobachten Sie die Trefferquote unter Setup > Systeminformationen, Feld Datenbankabfragen.
Um ihn auszuschalten, setzen Sie Mode=off und gehen genauso vor; nichts muss gelöscht werden. Die Schaltflächen unter
Setup > Caches und Setup > Systeminformationen (den Cache leeren, seine Zähler zurücksetzen) brauchen die Richtlinie
setup/managecache.
Was normal ist, worauf Sie achten
- Eine Trefferquote von 30 bis 40 Prozent direkt nach einem Leeren oder einem Neustart, die steigt, während Seiten besucht werden.
- Der SQL-Profiler zählt nur Anweisungen, die die Datenbank erreicht haben: Eine warme Seite mit geteiltem Cache zeigt 0 (Langsame Abfragen finden).
| Symptom | Ursache |
|---|---|
| Eine Seite zeigt nach einer Änderung außerhalb von Exponential alte Daten | den Abfrage-Cache leeren, wie oben |
| Die Trefferquote bleibt niedrig | eine Tabelle, die die Seiten lesen, wird bei jeder Anfrage beschrieben; die Systeminformationen listen die zuletzt beschriebenen Tabellen; schließen Sie sie aus oder korrigieren Sie den Schreiber |
Viele Dateien in entries/ | der Teil cache_cleanup läuft nicht |
| APCu voll, andere Caches verdrängt | ApcuReserve über 0 halten, MaxRows oder MaxAge senken oder apc.shm_size erhöhen |
state.ser nicht schreibbar | var/<site>/cache/querycache/ muss für jeden Benutzer schreibbar sein, unter dem die Website läuft |
| „Schreibvorgänge konnten die Sperre des Zustands nicht nehmen“ in den Systeminformationen | machen Sie state.lock für jeden Benutzer schreibbar, unter dem die Website läuft (auf NFS: NFSv4 oder lockd), und leeren Sie danach den Query-Cache |
Setzen Sie im Zweifel Mode=off und vergleichen Sie.
Checkliste
- To do: Jede Betriebsanleitung, die außerhalb von Exponential in die Datenbank schreibt, endet mit dem Leeren des Abfrage-Cache.
- To do:
cache_cleanupist eingeplant, wennStoragefileist oderautoohne APCu. - To do: Trefferquote und APCu-Speicher werden nach dem Umstellen auf
sharedbeobachtet.
Verwandte Seiten
- Leistung und Skalierung
- Caches
- Caching-Ebenen (für Hosting-Unternehmen)
- Freie Dokumentation: Diese Seite darf unter der GNU FDL 1.3 frei kopiert, übersetzt und verbessert werden.
Werden Sie Exponential-Partner
Partner teilen ihre Informationen, stellen Mittel bereit, geben Beiträge zurück und entwickeln die Produkte mit uns, und so wächst Exponential. Eine Partner-Website und ein Dashboard sind für Mitte 2027 geplant: Werden Sie noch heute Partner, damit wir schneller wachsen und neue Funktionen früher liefern.