JPA 2 - 如何缓存/优化计数查询?

时间:2011-09-08 08:18:11

标签: query-optimization jpa-2.0 eclipselink java-ee-6

我有Java EE应用程序,我有组列表。我想显示每个组中的项目数,所以我这样做:

SELECT COUNT(p) FROM Product p WHERE LOWER(p.group) = LOWER(:group)

Group是plain String。

问题是当我有50多个组时,加载页面的时间大约是10秒,这是不可接受的。当我删除计数时间下降到~1s。我该如何优化/缓存这个?

我的第一个想法是使用EJB单例来保持本地计数并使用EJB计时器刷新它们。

我在同一台机器上使用glassfish v3,eclipselink和oracle 10g数据库。 我在eclipselink中使用缓存,但似乎没有缓存计数查询。

<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.cache.size.default" value="500"/>

3 个答案:

答案 0 :(得分:1)

如何在一个查询中选择所有组和关联计数?这不是JPA的答案,而是一个简单的SQL:

SELECT LOWER(p.group), COUNT(*) 
FROM Product p
GROUP BY LOWER(p.group)

答案 1 :(得分:0)

如果你传递:group作为参数,我会将降低部分委托给java代码。

SELECT COUNT(p) FROM Product p WHERE LOWER(p.group) = (:groupInLower)

无论如何,这可能已经被SQL解释器优化了,但是值得一试......

答案 2 :(得分:0)

长查询通常是数据库中缺少索引的标志。尝试在product(lower(group))上添加索引。

此外,很难说知道精确的用例,但我发现在产品表中使用组标签获取组的产品数量很奇怪。您是否应该拥有Group实体,并在产品表中引用该组的主键?这样就无需在lower(group)上建立索引(但需要product.group_id上的索引)。