我有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"/>
答案 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
上的索引)。