回答:
メーリングリストのトピックの 1つに興味があるかもしれません。TomLane (コア開発者)が答えています。
[..]しかし、私の意見では、LRUキャッシングアルゴリズムよりも賢いと思っている人は一般的に間違っています。テーブルが非常に頻繁に使用される場合、メモリ内に問題なく残ります。LRUアルゴリズムに従ってメモリ内にとどまるほど十分に使用されていない場合は、メモリスペースを実際に他の何かに費やす必要があります。[..]
また、SOの質問に興味があるかもしれません:https : //stackoverflow.com/questions/486154/postgresql-temporary-tablesおよび多分より快適なhttps://stackoverflow.com/questions/407006/need-to-load-the -whole-postgresql-database-into-the-ram
Postgres 9.4は、最終的にリレーションからOSまたはデータベースバッファーキャッシュにデータをプリロードするための拡張機能を追加しました(任意)。
pg_prewarm
これにより、フル稼働パフォーマンスをより迅速に達成できます。
データベースで1回実行します(詳細な手順はこちら):
CREATE EXTENSION pg_prewarm;
その後、特定のリレーションをプリロードするのは簡単です。基本的な例:
SELECT pg_prewarm('my_tbl');
my_tbl
検索パスで指定された最初のテーブルを見つけて、それをPostgresバッファキャッシュにロードします
または:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
サポートされている場合、オペレーティングシステムに非同期プリフェッチ要求を発行します。サポートされていない場合は、エラーをスローします。read
要求されたブロックの範囲を読み取ります。とは異なりprefetch
、これは同期であり、すべてのプラットフォームとビルドでサポートされていますが、より遅い場合があります。buffer
要求されたブロックの範囲をデータベースバッファキャッシュに読み込みます。
デフォルトはでbuffer
、これは最大の影響(コストが高く、効果が大きい)を持っています。
詳細についてはマニュアルを参照してください、引用はそこからです。
Depeszもそれについてブログに書いています。
一般的な場合、十分なRAMがあれば、通常はデータベースサービスを信頼して、RAMで定期的に使用するものを適切に保持することができます。一部のシステムでは、テーブルを常にRAMに保持するようにヒントを出すことができます(頻繁に使用されない小さなテーブルに便利ですが、使用するときはできるだけ早く応答することが重要です)が、pgsqlにそのようなテーブルヒントがある場合他のものをキャッシュするために使用できるメモリ量を減らしているため、アプリケーション全体の速度が低下する可能性があるため、これらの使用には非常に注意する必要があります。
起動時にデータベースのページキャッシュを準備する場合(たとえば、再起動や、DBがキャッシュされているものをすべて忘れるようなメンテナンス操作の後)、次のスクリプトを作成します。
SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>
(最後のステップが各インデックスまたはコースに対して繰り返され、ORDER BY句のフィールドが正しい順序になるように注意してください)
上記を実行すると、すべてのデータとインデックスページが読み込まれ、RAMページキャッシュに(少なくともしばらくは)読み込まれるはずです。アプリケーションデータベース用のこのようなスクリプトは、再起動後に実行されるため、その後システムにログインする最初のユーザーの応答が遅くなることはありません。データベース定義テーブル(MSSQLのsys.objects
/ sys.indexes
/ など)をスキャンする代わりに、このようなスクリプトを手書きする方が良いsys.columns
でしょう。その後、時間がかかるすべてをスキャンするのではなく、最も一般的に使用されるインデックスを選択的にスキャンできます。
SELECT * FROM schema.table
60GiBテーブル全体を100GiB PostgreSQLバッファキャッシュにロードしようとしました。
同様の問題がありました:
サーバーサービスを再起動し、キャッシュされたデータがすべて削除された後、必要なすべてのインデックスとデータがキャッシュされるまで、多くのクエリが最初に呼び出され、本当に遅くなり、クエリの特定の複雑さが発生しました。つまり、たとえば、ユーザーは「アイテム」ごとに1回(実行時間1〜3秒)および関連データを5,000万行からヒットする必要があるため、ユーザーは不要な遅延を経験しなくなります。ユーザーが迷惑なハングを経験するまでに最初の3時間かかります。ほとんどの使用済みデータがキャッシュされ、プログラムが実稼働パフォーマンスで一流を台無しにし、それでも2日目は、わずかにアクセスされたデータが少なくなると突然の短い遅延が続きます... 、統計データなど。
これを解決するために、大きなインデックスを持つ最も使用量の多いテーブルで選択を実行する小さなpythonスクリプトを作成しました。実行に15分かかり、パフォーマンスの遅延はありませんでした。
うーん、COPYコマンドが役立つかもしれません。COPYを実行してstdoutから読み取ります。pg_dumpを使用して実行できます。
pg_dump -U <user> -t <table> <database> > /dev/null
他の方法は、すべてのテーブルファイルを見つけて実行することcat <files> > /dev/null
です。
テーブルのファイル名を取得する方法の例を次に示します。
# 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
そのため、テーブルのファイルは/ path / to / pgsql / data / base / 16384/24576 *です
インデックスとトーストテーブルも同様に読み取り、それらのOIDを同じ方法で取得したいと考えています。
ところで、なぜあなたはそれが必要なのですか?postgresqlとOSは、最もホットなデータをキャッシュし、良好な状態を維持するのに十分スマートだと思います。キャッシュ効率。
QSoftのRamDriveを使用します。これは、Windows用の最速のRAMディスクとしてベンチマークされました。使ったばかり
initdb -D e:\data
ここで、e:\はRamDiskの場所です。