web-dev-qa-db-ja.com

db_query()の結果をキャッシュするにはどうすればよいですか?

views_get_view_result()を使用して、ビューから結果を取得しました。クエリ結果はめったに変更されません。 6日間ビューのキャッシュを使用できました。

db_query()への呼び出しに変換したい場合、どのようにキャッシュを有効にできますか?

9
uwe

ビューまたはdb_query()を使用する場合、キャッシュの問題はありません。キャッシングは常に同じように動作し、キャッシュミスが発生したときにデータをフェッチする方法は完全にあなた次第です。

  1. キャッシュエントリを識別するためのキャッシュIDを作成します。単純なハードコードされた文字列、または引数などに基づいた複雑な文字列を使用できます。
  2. キャッシュからロードできるかどうかを確認します。
  3. そうでない場合は、データを再構築し、必要な有効期限でキャッシュに入れます。

いくつかの例を見るには、 variable_initialize() などの cache_get()を使用する関数 をご覧ください。

関数が複数回呼び出された場合、おそらくそれを静的キャッシュと組み合わせる必要があります。たとえば archiver_get_info() を参照してください。また、データの再構築が本当に遅い場合は、variable_initialize()のようにロックフレームワークを使用することで、データの再構築が複数回発生するのを防ぐことができます。

Memcacheのような代替キャッシュバックエンドを使用しない限り、cache_get()もdbクエリであるため、単一のクエリのキャッシュは遅いクエリの場合にのみ意味があることに注意してください。

最後に、ビューにはキャッシュが組み込まれており、ビューで構成できます。だから、それもオプションかもしれません。

9
Berdir

DBレイヤーにはキャッシングメカニズムが組み込まれているとは思いませんが(私は間違っているかもしれません)、デフォルトのキャッシュAPIを利用することができます。

これは、クエリの結果をキャッシュして特定のタイプのノードを取得する基本的な例にすぎません。

function MYMODULE_get_nodes_by_type($type) {
  // Setup a cache ID
  $cid = 'MYMODULE:node_types:' . $type;

  // If a cached entry exists, return it
  if ($cached = cache_get($cid)) {
    return $cached->data;
  }

  // Otherwise load the data
  $data = db_query('SELECT * FROM {node} WHERE type = :type', array(':type' => $type))->fetchAll();

  // And cache it
  cache_set($cid, $data, 'cache', strtotime('+6 days'));
}
7
Clive

私は最近 キャッシュアクション モジュールを発見しました。このモジュールを使用すると、ビューのキャッシュをルールによってトリガーされるキャッシュに設定し、特定のビューおよびビューの表示でキャッシュを無効にするルールを作成できます。

たとえば、特定のコンテンツタイプのノードを一覧表示するビューのキャッシュは、そのコンテンツタイプの新しいノードが作成されるときに空にすることができます。

3
weekbeforenext

標準の cache_set / cache_get メカニズムに加えて、Drupalが提供するメカニズム。MySQLをデータベースとして使用している場合は、 query cache は、ビューやその他のデータベースクエリの結果を透過的にキャッシュできます mysqltuner は、キャッシュサイズの適切な値を把握するのに役立ちます。

データベースへの大量の書き込みを行っている場合、キャッシュの無効化戦略が機能するため、クエリキャッシュの効果が低下することに注意してください(テーブルへの書き込みにより、そのテーブルからSELECT FROMまたはJOINするすべてのエントリが無効になります)。

PostgreSQLのキャッシュメカニズム もありますが、私は直接の経験はありません。

3
mpdonadio