2010-03-11 53 views
0

我使用JBoss的EJB 3.0实现(JBoss的4.2.3服务器) 一开始,我创建的本机查询使用建设所有的时间像如何缓存在EJB和返回结果效率(性能POV)

Query query = entityManager.createNativeQuery("select * from _table_"); 
查询

虽然效率不高,但我进行了一些测试,发现它确实需要很多时间...然后我找到了一个更好的方法来处理它,使用注释来定义原生查询:

@NamedNativeQuery(name = "fetchData", value = "select * from _table_", resultClass=Entity.class) 

然后就用它

Query query = entityManager.createNamedQuery("fetchData"); 

上面的代码行的性能比,我从开始更好的两倍,但还是不如我想象的那么好......后来我发现,我可以切换到休眠标注为NamedNativeQuery(反正,JBoss的实现EJB是基于Hibernate),并加入一两件事:

@NamedNativeQuery(name = "fetchData2", value = "select * from _table_", resultClass=Entity.class, readOnly=true) 

readOnly - 标记的结果是否在只读模式或不取。这听起来不错,因为至少在我的这种情况下,我不需要更新数据,我只是想获取报告。当我开始服务器测量性能时,我注意到没有readOnly = true的查询(默认情况下它是false)返回每次迭代的结果越来越好,同时另一个(fetchData2)的工作方式类似于“稳定”并且具有时间差异他们之间越来越短,经过双方的5次迭代的速度几乎是一样的...

的问题是:

1)是否有任何其他方式使用最多加快查询?似乎命名查询应该准备一次,但我不能说...事实上,如果要创建查询一次,然后只是使用它,从性能的角度来看会更好,但是缓存这个对象是有问题的,因为在创建查询后,我可以设置参数(当我在查询中使用“:variable”时),并且它改变了查询对象(不是吗?)。那么,在这里有什么方法来缓存它们?或者命名查询是我可以使用的最佳选择?

2)任何其他方法如何使结果更快地读取。我的意思是,例如我不需要这些实体被连接,我不会更新它们,我需要的只是获取数据集合。也许readOnly是唯一可用的方式,所以我不能加快速度,但谁知道:)

P.S.我没有询问数据库性能,现在我需要的是如何不一直创建查询对象,所以请高效使用它,并且“允许”EJB以较少的工作完成与返回数据相同的结果。

添加15.03.2010:
通过查询我的意思是查询对象(所以如何缓存此对象重用);并且缓存查询结果对我来说不是一个解决方案,因为查询中的原因对于每个查询而言可能几乎是唯一的,因为其中存在浮点指向参数。 Cache不会理解“a> 50.0001”和“a> 50.00101”可以给出相同的结果,但也不能。

回答

0

您可以使用second level cachequery cache来避免碰到数据库(对于只读对象来说工作得特别好)。 Hibernate支持二级缓存(使用第三方缓存提供程序),但它是JPA 1.0的扩展。

+0

谢谢你的回复。 在许多情况下,我无法避免碰到数据库,因为我在表中有mlns的数据,而且我获取的内容取决于输入参数,并且由于浮点输入数据在大多数情况下使用where子句中的参数进行选择将是唯一的。它没有足够的内存来缓存它......这就是为什么我尽可能优化EJB/Hibernate代码(查询创建;数据转换......) – Maxym 2010-03-14 16:57:57

+0

以及可以缓存的内容我以自己的方式完成了它,所以二级缓存可以是我的缓存策略的另一种选择...谢谢! – Maxym 2010-03-14 17:00:18

+0

@Maxym *“使用where子句中的参数选择将是唯一的”*啊,我明白了,实际上,查询缓存将不是一个解决方案。但这个问题并不明显。也许你应该提到这一点。 – 2010-03-14 17:23:00