10

この質問に関連する

前提:

これらは、私の読書、経験、理解に基づく私の仮定です。間違っている可能性があります。間違っている場合は、コメントしてください。質問を編集します。

  • クエリ キャッシュは、主に第 2 レベルのキャッシュと共に優れています
  • クエリ キャッシュは、クエリ + パラメータの識別子の結果をキャッシュします
  • データベースが変更され、キャッシュに反映されていない場合、クエリキャッシュは危険です

質問:

第 2 レベルのキャッシュにないオブジェクトがあります。不適切なプログラミングまたはその他の制約により、オブジェクトをロードするコードが同じ休止状態セッションで複数回呼び出されています。検索はHQL検索クエリを使用しています。

 hibernateTemplate.find("from Foo f where f.bar > ?", bar);

クエリ キャッシュを追加する前に、上記のコードが同じ Hibernate セッション内で N 回呼び出された場合、データベースへのヒット数は N 回でした。

次に、クエリ キャッシュを追加するとどうなるかを確認したかったのです。

 Query query = session.createQuery("from Foo f where f.bar > ?");
 query.setCacheable(true);
 query.setParameter(bar);
 query.list();

クエリキャッシュを追加したとき、同じセッション中に、休止状態がデータベースに N 回ヒットせず、セッションごとに 1 回だけヒットすることに気付きました。

  1. したがって、私の最初の仮定は、Hibernate が最初にセッション キャッシュを検索し、次に 2 番目のレベルのキャッシュを検索するということです。この仮定は正しいですか?
  2. Fooまた、第 2 レベルのキャッシュにないオブジェクト ( ) がデータベースで変更された場合、クロス セッション スコープのクエリ キャッシュが間違った識別子を返すため、間違ったオブジェクトが返されることも想定しています。あれは正しいですか?
  3. 2L キャッシュされていないオブジェクトであっても、不変の情報を含むクエリにクエリ キャッシュを使用することは、良い習慣であると言えますか? (例: where 句に常に同じ結果を返す条件が含まれるクエリ。例: "select p.ser_num where p.id = ?" ser_num と id の組み合わせが一度作成されると変更されない場合)

ところで、関連する質問では、クエリ キャッシュはセッション キャッシュ スコープでは機能しないと主張されています。私はその主張を誤解していますか、それとも何か他のものですか?

4

3 に答える 3

7

クエリ キャッシュは、特定のタイプの第 2 レベル キャッシュです。あなたが第 2 レベルのキャッシュと呼んでいるものは、「オブジェクト キャッシュ」と呼びたいと思います。

あなたの仮定についてのコメント:

  • クエリ キャッシュは、主に第 2 レベルのキャッシュ (別名オブジェクト キャッシュ) と一緒に使用すると効果的です。

クエリキャッシュは、クエリの生の結果のみを主キーとして保持します。休止状態で言えば、ID です。実際の水和オブジェクトは保持されません。これは、jdbc を使用してクエリを実行すると、ResultSet を反復処理するときに実際にハイドレートされた (入力された) オブジェクトのみが返されるため、理にかなっています。発言は必ずしも正しいとは限りません。クエリが非常に複雑で、実行に非常に長い時間がかかる場合、クエリ キャッシュを使用すると、その時間を節約できます。クエリ キャッシュを使用しても、データベースからオブジェクトをロードするのにかかる時間を節約することはできません。

  • データベースが変更された場合、クエリキャッシュは危険であり、キャッシュに反映されませんでした

これは事実ですが、クエリ キャッシュに固有のものではありません。第 2 レベル キャッシュと呼ばれるものにも同じことが当てはまりますが、通常はオブジェクト キャッシュと呼ばれるものです。

したがって、私の最初の仮定は、Hibernate が最初にセッション キャッシュを検索し、次に 2 番目のレベルのキャッシュを検索するということです。この仮定は正しいですか?

はい、オブジェクトをロードするとき、これは動作です。

また、第 2 レベルのキャッシュにないオブジェクト (Foo) がデータベースで変更された場合、クロス セッション スコープのクエリ キャッシュが間違った識別子を返すため、間違ったオブジェクトが返されることも想定しています。あれは正しいですか?

はい、オブジェクト キャッシュとクエリ キャッシュの両方が影響を受けます。これは、休止状態を経由せずにデータベースが変更された場合にのみ問題になります。クエリ キャッシュのタイムアウトを設定することで、この影響を軽減できる可能性があります。

2L キャッシュされていないオブジェクトであっても、不変の情報を含むクエリにクエリ キャッシュを使用することは、良い方法であると言えますか? (例: where 句に常に同じ結果を返す条件が含まれるクエリ。例: "select p.ser_num where p.id = ?" ser_num と id の組み合わせが一度作成されると変更されない場合)

この種のオブジェクトでは、オブジェクト キャッシュとクエリ キャッシュの両方を使用しない理由はありません。

はい、クエリ キャッシュはセッション レベル、つまりレベル 1 キャッシュでは機能しません。したがって、クエリを再度実行すると、データベースに再度ヒットする理由です。クエリの結果 (ID セット) をセッション キャッシュに入れません。

于 2010-01-04T11:04:50.760 に答える
1

あなたの質問 #3 については、オブジェクトがキャッシュされていないときにクエリ キャッシュを使用したくないと思います。最終的にはすべてのプライマリ ID が取得されますが、オブジェクトを取得するためにキーごとに 1 回データベースにアクセスする必要があり、キャッシュをまったく使用せずにクエリを実行するよりも遅くなる可能性があります。いずれにせよ、3.3 の時点では、より新しいバージョンでは、たとえば where id in (:id1,:id2,...) など、より少ないクエリを使用して欠落しているオブジェクトを取得する可能性があります。

于 2010-01-04T20:04:23.900 に答える