JPA 2 - Как кэшировать / оптимизировать количество запросов? - PullRequest
1 голос
/ 08 сентября 2011

У меня есть приложение Java EE, где у меня есть список групп. Я хочу отобразить количество элементов в каждой группе, поэтому я делаю:

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

Группа простая строка.

Проблема в том, что когда у меня более 50 групп, время загрузки страницы составляет около 10 секунд, что недопустимо. Когда я снимаю счет, время падает до ~ 1с. Как я могу оптимизировать / кэшировать это?

Моей первой идеей было использование синглтона 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 ]

1 голос
/ 08 сентября 2011

Как насчет выбора всех групп и связанных количеств в одном запросе?Это не ответ JPA, а простой SQL:

SELECT LOWER(p.group), COUNT(*) 
FROM Product p
GROUP BY LOWER(p.group)
0 голосов
/ 08 сентября 2011

Длинный запрос обычно является признаком отсутствия индекса в базе данных.Попробуйте добавить индекс на product(lower(group)).

Кроме того, трудно сказать, не зная точного варианта использования, но я нахожу странным получать количество продуктов группы, используя метку группы в таблице продуктов.Разве у вас не должно быть объекта группы и ссылка на первичный ключ группы в таблице продуктов?Это исключило бы необходимость индекса на lower(group) (но потребовал бы индекс на product.group_id).

0 голосов
/ 08 сентября 2011

Если вы все равно передаете :group в качестве параметра, я бы делегировал нижнюю часть в код Java.

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

В любом случае интерпретатор SQL мог бы оптимизировать его, но попробовать стоит ...

...