2

我的代码有时会以相当闲聊的方式进行大量数据库查询:

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

}

上面的代码只从特殊的管理页面调用,所以它不必非常快,但我想达到合理的性能。有没有一种通用的方法可以在不完全重写的情况下做到这一点?

我想象的是一个播放模块,它可以实现以下功能:

// 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 有几个选项可以打开二级缓存,尽管这样做并非易事。如果你必须使用缓存,你应该看看那里。

有关概述,请参见http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-cache和http://www.ehcache.org/documentation/user-guide/为流行的 Ehcache 选项休眠

当然,这不仅会影响您的管理后端代码,还会影响所有数据库访问。

这就是说,我建议您调整代码而不是实现缓存。

于 2012-08-14T12:42:31.430 回答
1

默认情况下,Play 不启用休眠 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 回答