2011-05-20 92 views
4

我正在开发一个MVC应用程序与NHibernate使用会话每请求模式。大多数时候用户只是读取数据,因此我试图通过以下方式使用NHibernate的二级缓存:我已经安装了SysCache并使所有持久化实体都可缓存(缓存使用率=“非严格读写” )和在应用程序启动我打电话从数据库加载所有常用的实体,像这样:NHibernate二级缓存性能问题

var all = Session.QueryOver<T>().Cacheable().List<T>() 

出于评估目的,我跟踪执行时间上面的调用和大约50000结果是〜5秒,第时间和约2.5秒的任何后续调用缓存查询.... NHibernate Profiler说,对数据库的查询不到100ms,那么需要那么多时间?我尝试过切换提供程序,但使用Velocity和Memcached获得了类似的结果(如果不是更糟)......我几乎读到了关于NHibernate及其二级缓存使用的所有信息,尽管我可能并不完全正确,但我认为在上面的语句中会发生什么情况是:构造50000个对象,并将其数据存储在实体中,并查询缓存和保存在时间戳缓存中的会话时间戳。如何在i5机器上花费5秒?即使这是正常的,在随后的调用中如何读取缓存的数据需要2.5秒,而不需要更改?由于我对NHibernate相对来说比较新,所以你们能帮我弄清楚我做错了什么吗?任何帮助将不胜感激...我一直在我的头撞墙一个星期了...

回答

4

你不应该放50000实体在你的缓存,否定了一个数据库,特别是如果你的数据来自SELECT * FROM TABLE。如果它来自一个非常昂贵的查询,那么缓存成本低于查询开销,并且应该放入缓存中。

使用查询获取特定数据。然后,查找进行大多数查询的页面,并根据需要使用缓存对其进行优化。

+0

感谢您的快速回复。虽然我最近已经认识到,你所说的确实是使用NH的方式(以及像我这样的非特定查询甚至在NH分析器中触发警报),只应该昂贵的查询被缓存,只要DB中的数据很少改变?另外,我正在努力设计数据访问层,以便只发布具有绑定结果集的特定查询或查询,但是,我对可能导致我引用的语句的巨额成本的原因感兴趣,以发现我可能有的任何缓存问题... – 2011-05-20 08:36:06

+1

对经常调用的查询使用缓存,并根据更改频率设置到期日期。 – mathieu 2011-05-20 08:46:56

+1

只是为了扩展@ mathieu的非常正确的答案 - 我相信你的假设是正确的:长时间的执行时间源于nHib缓存实际上只保存缓存对象及其值的属性,而不是整个对象。对象本身是在每次读取时构建的。所以这些是你的2.5秒。 – 2011-05-21 13:37:49