Я использую реализацию JBoss EJB 3.0 (сервер JBoss 4.2.3)
В начале я все время создавал нативный запрос, используя конструкцию типа
Query query = entityManager.createNativeQuery("select * from _table_");
Конечно, это не так эффективно, я выполнил несколько тестов и обнаружил, что это действительно занимает много времени ... Затем я нашел лучший способ справиться с этим, использовать аннотацию для определения собственных запросов:
@NamedNativeQuery( name = "fetchData", value = "select * from _table_", resultClass=Entity.class )
, а затем просто используйте его
Query query = entityManager.createNamedQuery("fetchData");
производительность строки кода выше в два раза лучше, чем там, где я начал, но все же не так хорошо, как я ожидал ... потом я обнаружил, что могу переключиться на аннотацию Hibernate для NamedNativeQuery (во всяком случае, реализация EJB JBoss на основе Hibernate) и добавьте еще одну вещь:
@NamedNativeQuery( name = "fetchData2", value = "select * from _table_", resultClass=Entity.class, readOnly=true)
readOnly - отмечает, выбираются ли результаты в режиме только для чтения или нет. Звучит хорошо, потому что, по крайней мере, в моем случае мне не нужно обновлять данные, я просто хочу получить их для отчета. Когда я запустил сервер для измерения производительности, я заметил, что запрос без readOnly = true (по умолчанию это false) возвращает результат с каждой итерацией все лучше и лучше, и в то же время другой (fetchData2) работает как «стабильный» и с разницей во времени между ними все короче и короче, а после 5 итераций скорость обоих была почти одинаковой ...
Вопросы:
1) Есть ли другой способ ускорить использование запроса? Кажется, что именованные запросы должны быть подготовлены один раз, но я не могу сказать это ... На самом деле, если создать запрос один раз, а затем просто использовать его, было бы лучше с точки зрения производительности, но кешировать этот объект проблематично, потому что после создания запроса я могу установить параметры (когда я использую «: переменную» в запросе), и это меняет объект запроса (не так ли?). ну есть ли способ их кешировать? Или именованный запрос - лучший вариант, который я могу использовать?
2) любые другие подходы к ускорению получения результатов. Я имею в виду, например, что мне не нужно, чтобы эти сущности были присоединены, я не буду обновлять их, все, что мне нужно, это просто получить сбор данных. Может быть, readOnly - единственный доступный способ, поэтому я не могу ускорить его, но кто знает :)
P.S. Я не спрашиваю о производительности БД, все, что мне сейчас нужно, это как не создавать объект запроса постоянно, поэтому используйте его эффективно и «разрешите» EJB выполнять меньше работы с тем же результатом в отношении возврата данных.
Добавлено 15.03.2010:
Под запросом я имею в виду объект запроса (так, как кэшировать этот объект для повторного использования); и кэширование результатов запроса не является для меня решением, поскольку причина в запросе может быть почти уникальной для каждого запроса из-за параметров, указывающих на плавающее число. Кэш просто не поймет, что «a> 50.0001» и «a> 50.00101» могут дать одинаковый результат, но также не могут.