2

私のコードは、かなりおしゃべりな方法で、多くの DB クエリを作成することがあります。

// Process all users:
for (User u : users) {
  // multiple queries per single user
  w = Website.find("owner = ?", u.id);
  d = Demo.find("...");
  ...

}

上記のコードは特別な管理ページからのみ呼び出されるため、超高速である必要はありませんが、妥当なパフォーマンスを実現したいと考えています。完全に書き直さずにこれを行う一般的な方法はありますか?

私が想像しているのは、次のようなものを可能にする Play モジュールです。

// Preprocess - warm cache
Website.findAll();
Demo.findAll();

// After the above code was run, all the data is cached in the scope of this request, so
// the following code should now not do any fetches to the database

// Process all users:
for (User u : users) {
  // multiple queries per single user
  w = Website.find("owner = ?", u.id);
  d = Demo.find("...");
  ...

}

このような最適化レイヤーを構築しようとするのは正しいですか? どのようにアプローチしますか?

私が見ている利点は、これにより、プロトタイピング段階で「ばかげたコードを書く」ことができ、必要なときに適切なレベルに簡単に最適化できることです。もちろん、最適なパフォーマンスには達せず、非常に大きなテーブルでは機能しませんが、特定のタスクでは有益な場合があります。

それとも...「魔法の」キャッシュレイヤーに頼らずに、それを飲み込んで、代わりにコードを最初から書き直す必要がありますか?

4

2 に答える 2

1

Hibernate には、第 2 レベルのキャッシュを有効にするオプションがいくつかありますが、そうするのは簡単ではありません。キャッシュを使用する必要がある場合は、そこを確認する必要があります。

概要についてはhttp://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-cacheおよびhttp://www.ehcache.org/documentation/user-guide/を参照してください。人気のある Ehcache オプションの休止状態。

もちろん、これは管理者のバックエンド コードだけでなく、すべての DB アクセスにも影響します。

つまり、キャッシュを実装する代わりにコードを調整することをお勧めします。

于 2012-08-14T12:42:31.430 に答える
1

Play では、Hibernate の第 2 レベルのキャッシュはデフォルトで有効になっていません。パフォーマンスを改善する必要がある場合は、再生キャッシュを直接使用できます。データがキャッシュに存在しない可能性があり、ミス時にデータを取得する必要がある場合があることに注意してください。

また、キャッシュのメモリ コストにも注意してください。

for (User u : users) {
  WebSite www = Cache.get("website-"+u.id, WebSite.class);
  if(www == null){
     // multiple queries per single user
     www = Website.find("owner = ?", u.id);
     Cache.set("website-"+u.id, www, "1d");
  } 
  ...
}

試したことはありませんが、休止状態の二次キャッシュの有効化に関するこのスレッドを見てください。

また、データベースに正しいインデックスが作成されていることを確認する必要があります。これは、重いクエリのパフォーマンスに大きな影響を与える可能性があります。

于 2012-08-14T12:50:40.760 に答える