質問

PostgreSQLに特定のテーブルをメモリにロードするように強制する体系的な方法はありますか、それともシステムによってキャッシュされるようにディスクからそれを読み取っていますか?

役に立ちましたか?

解決

あなたはその1つで間違っているかもしれません メーリングリストのトピック, 、それはTom Lane(Core Dev)による回答です:

..]しかし、私の意見では、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

他のヒント

ポストグレス9.4 最終的に、関係からデータをOSまたはデータベースバッファーキャッシュにプリロードするための拡張機能を追加しました(選択して):

pg_prewarm

これにより、完全な操作パフォーマンスに迅速に到達できます。

データベースで1回実行します(詳細な手順 ここ):

CREATE EXTENSION pg_prewarm;

次に、特定の関係をプリロードするのは簡単です。基本例:

SELECT pg_prewarm('my_tbl');

名前の最初のテーブルを見つけます my_tbl 検索パスでポストグラスバッファキャッシュにロードします

または:

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>

(各インデックスまたはコースでその最後のステップが繰り返され、適切な順序で条項ごとにフィールドを順序にするように注意してください)

上記のすべてのデータとインデックスページを実行した後、読み取られるはずであるため、RAMページのキャッシュに表示されます(少なくとも当面は)。アプリケーションデータベースにはこのようなスクリプトがあります。これは、再起動後に実行されるため、最初のユーザーがその後システムにログインしても、応答性が遅くなりません。 DB定義テーブルをスキャンする代わりに、そのようなスクリプトを手作業で作成する方が良いです( sys.objects/sys.indexes/sys.columns MSSQL)では、スキャンするのではなく、最も一般的に使用されるインデックスを選択的にスキャンできます。 すべての 時間がかかります。

同様の問題がありました:
サーバーサービスとすべての現金データがドロップされた後、すべての必要なインデックスとデータが現金化されるまで、非常に遅く、クエリの特定の複雑さの原因で、初めての多くのクエリが初めて呼ばれます。つまり、たとえば、ユーザーはすべての「アイテム」(1〜3秒のexec時間)と5,000万行の関連データを1回ヒットする必要があるため、ユーザーは不要な遅延を発生しなくなります。ユーザーが迷惑なハングを体験するのに最初の3時間かかります。ほとんどの使用されたデータが現金化され、プログラムが生産パフォーマンスで最高のノッチを台無しにするまで、その後、2日間の突然の短い遅延で、初めてのアクセスデータを少なくしたときに... 、統計データなど。

これを解決するために、大きなインデックスを備えた最も重い使用されたテーブルで選択を実行する小さなPythonスクリプトを書きました。実行に15分かかり、パフォーマンスの遅れはありませんでした。

うーん、コピーコマンドが役立つ場合があります。コピーを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*です

Migthはインデックスとトーストテーブルも読みたいと思っており、同じようにOIDを取得します。

ところで、なぜあなたはそれが必要なのですか? PostgreSQLとOSは、最もホットなデータをキャッシュして良好に維持するのに十分賢いと思います。キャッシュ効率。

私が使う ramdrive QSOFTから ベンチマーク Windowsの最速のRamdiskとして。使用したばかりです

initdb -D e:\data

ここで、e:はラムディスクの場所です。

ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top