Gibt es eine systematische Möglichkeit, PostgreSQL zu zwingen, eine bestimmte Tabelle in den Speicher zu laden oder sie zumindest von der Festplatte zu lesen, damit sie vom System zwischengespeichert wird?
Gibt es eine systematische Möglichkeit, PostgreSQL zu zwingen, eine bestimmte Tabelle in den Speicher zu laden oder sie zumindest von der Festplatte zu lesen, damit sie vom System zwischengespeichert wird?
Antworten:
Möglicherweise interessieren Sie sich für eines der Mailinglisten-Themen , das von Tom Lane (Core-Entwickler) beantwortet wird:
[..] Aber ich bin der Meinung, dass Leute, die sich für schlauer halten als ein LRU-Caching-Algorithmus, in der Regel falsch liegen. Wenn der Tisch stark ausgelastet ist, bleibt er in guter Erinnerung. Wenn es nicht stark genug genutzt wird, um nach einem LRU-Algorithmus im Speicher zu bleiben, sollte der Speicherplatz möglicherweise wirklich für etwas anderes verwendet werden. [..]
Sie könnten auch an einer SO-Frage interessiert sein: https://stackoverflow.com/questions/486154/postgresql-temporary-tables und möglicherweise geeigneter https://stackoverflow.com/questions/407006/need-to-load-the -Postgresql-Datenbank-in-den-RAM
Postgres 9.4 fügte schließlich eine Erweiterung hinzu, um Daten aus Relationen vorab in den Cache des Betriebssystems oder des Datenbankpuffers zu laden (nach Ihrer Wahl):
pg_prewarm
Dies ermöglicht ein schnelleres Erreichen der vollen Betriebsleistung.
Führen Sie einmal in Ihrer Datenbank aus (detaillierte Anweisungen hier ):
CREATE EXTENSION pg_prewarm;
Dann ist es einfach, eine bestimmte Relation vorzuladen. Einfaches Beispiel:
SELECT pg_prewarm('my_tbl');
Findet die erste my_tbl
im Suchpfad angegebene Tabelle und lädt sie in den Postgres-Puffercache
Oder:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
Gibt asynchrone Prefetch-Anforderungen an das Betriebssystem aus, sofern dies unterstützt wird, oder gibt andernfalls einen Fehler aus.read
liest den angeforderten Blockbereich; Im Gegensatzprefetch
dazu ist dies synchron und wird auf allen Plattformen und Builds unterstützt, kann jedoch langsamer sein.buffer
Liest den angeforderten Blockbereich in den Datenbankpuffer-Cache.
Die Standardeinstellung ist buffer
, welche die größten Auswirkungen hat (höhere Kosten, beste Wirkung).
Lesen Sie das Handbuch für weitere Details , Zitate sind von dort.
Depesz hat auch darüber gebloggt .
Wenn Sie über genügend RAM verfügen, können Sie sich im Allgemeinen darauf verlassen, dass der Datenbankdienst die Dinge, die Sie regelmäßig im RAM verwenden, ordnungsgemäß verwaltet. Bei einigen Systemen können Sie angeben, dass die Tabelle immer im RAM gespeichert werden soll (dies ist nützlich für kleinere Tabellen, die nicht häufig verwendet werden, aber wenn sie verwendet werden, ist es wichtig, dass sie so schnell wie möglich reagieren). Wenn pgsql jedoch solche Tabellenhinweise enthält Sie müssen sehr vorsichtig mit ihnen umgehen, da Sie den für die Zwischenspeicherung von anderen Elementen verfügbaren Arbeitsspeicher verringern, sodass Sie Ihre Anwendung möglicherweise insgesamt verlangsamen.
Wenn Sie den Seitencache der Datenbank beim Start vorbereiten möchten (z. B. nach einem Neustart oder einer anderen Wartungsoperation, bei der die Datenbank alles vergisst, was zwischengespeichert wird), schreiben Sie ein Skript, das Folgendes ausführt:
SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>
(Dieser letzte Schritt wird für jeden Index oder Kurs wiederholt. Achten Sie darauf, dass die Felder in der ORDER BY-Klausel in der richtigen Reihenfolge angezeigt werden.)
Nach dem Ausführen des obigen Befehls sollten alle Daten- und Indexseiten gelesen worden sein und sich (zumindest vorerst) im RAM-Seiten-Cache befinden. Wir haben solche Skripte für unsere Anwendungsdatenbanken, die nach dem Neustart ausgeführt werden, damit die ersten Benutzer, die sich danach am System anmelden, nicht langsamer reagieren. Sie sind besser dran , eine solche Skript von Hand schreiben, statt Scannen der db Definitionstabellen (wie sys.objects
/ sys.indexes
/ sys.columns
in MSSQL), dann können Sie selektiv die Indizes scannen , die meisten sind ziemlich häufig verwendet als das Scannen alles , die länger dauern wird.
SELECT * FROM schema.table
die gesamte 60-GB-Tabelle in meinen 100-GB-PostgreSQL-Puffercache zu laden.
Ich hatte ein ähnliches Problem:
Nach dem Neustart des Serverdienstes und dem Löschen aller verrechneten Daten wurden viele Abfragen beim ersten Aufruf aufgrund der spezifischen Komplexität der Abfragen sehr langsam ausgeführt, bis alle erforderlichen Indizes und Daten verrechnet wurden. Dies bedeutet, dass Benutzer beispielsweise alle "Elemente" (1 bis 3 Sekunden Ausführungszeit) und die zugehörigen Daten aus 50 Millionen Zeilen einmal treffen müssen, damit keine unerwünschten Verzögerungen mehr auftreten. Es dauert die ersten 3 Stunden, bis Benutzer nervige Hänge feststellen, bis die meisten verwendeten Daten kassiert sind und Programme die Produktionsleistung auf höchstem Niveau ruinieren. Selbst dann enden 2 Tage mit ein paar plötzlichen kurzen Verzögerungen, wenn beim ersten Zugriff weniger Daten abgerufen werden ... , für Statistikdaten etc.
Um dies zu lösen, haben Sie ein kleines Python-Skript geschrieben, das Selects für am häufigsten verwendete Tabellen mit großen Indizes ausführt. Die Ausführung dauerte 15 Minuten, und es gab keine Leistungsverzögerungen.
Hmmm, vielleicht wäre ein COPY-Befehl hilfreich. Führen Sie einfach COPY to stdout aus und lesen Sie daraus. Es ist möglich, dies mit pg_dump zu tun:
pg_dump -U <user> -t <table> <database> > /dev/null
Eine andere Möglichkeit besteht darin, alle Tabellendateien zu finden und auszuführen cat <files> > /dev/null
.
Hier ist das Beispiel zum Abrufen von Tabellendateinamen:
# SELECT oid, datname FROM pg_database ;
oid | datname
-------+-----------
<...>
16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
oid | relname
-------+---------
24576 | fn
(1 row)
-- oid of our table is 24576
Die Datei (en) der Tabelle lauten also / path / to / pgsql / data / base / 16384/24576 *.
Sie möchten auch Indizes und Toast-Tabellen lesen und deren Oids auf die gleiche Weise erhalten.
BTW, warum brauchst du das? Ich glaube, Postgresql und OS ist klug genug, um die heißesten Daten zwischenzuspeichern und gut zu pflegen. Cache-Effizienz.
Ich benutze RAMDRIVE von QSoft, das wurde gebenchmarkt als der schnellste RAM - Disk für Windows. Ich habe gerade benutzt
initdb -D e:\data
Dabei ist e: \ der Ort der RamDisk.