Hibernate HQL createQuery

Я пытаюсь преобразовать старое приложение, выполняющее SQL-запросы старым способом, как показано ниже:

java.sql.Connection connection = ....
String queryStr="select acct from Person where acct in (select acct from Document where dbcreate_date > DATEADD(hh,-12, GETDATE())) and status not in ('A','P')";
...
...
java.sql.Statement statement = connection.createStatement(
                ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_READ_ONLY);
        rs = statement.executeQuery(queryStr);

Код выше занимает около 10 миллисекунд. Это включает в себя получение соединения с базой данных, создание оператора и выполнение запроса.

Сейчас я использую Hibenate HQL и создал HQL-запрос следующим образом:

Query query = session.createQuery("select p.acct   from Person p  where p.acct in (select  acct from Document d where create_date > :date and status not in ('A','P'))");

Теперь только этот оператор "session.createQuery(....)" занимает около 105 миллисекунд, что примерно в 10 раз дольше, чем выполнение всего запроса в старом порядке, как упоминалось выше.

Сейчас я не совсем уверен, как работает кэширование запросов в Hibernate, но если я выполню этот же оператор HQL во второй раз, это займет около 5 миллисекунд.

Теперь мой вопрос: почему такое поведение происходит с использованием Hibernate HQL? Кто-нибудь знает, что происходит внутри метода "session.createQuery(...)", который в первый раз занимает гораздо больше времени, а во второй раз - намного меньше? Я также заметил, что Hibernate выполняет SQL для базы данных оба раза при выполнении "query.list()".

Благодарю.

2 ответа

Решение

Попробуйте использовать собственный запрос в Hibernate, чтобы сравнить производительность:

Query query = session.createSQLQuery("select acct from Person where acct in (select acct from Document where dbcreate_date > DATEADD(hh,-12, GETDATE())) and status not in ('A','P')");

По спектаклю:

Вы на самом деле не сравниваете подобное с двумя вашими запросами.

Ваш первый пример, прямой запрос JDBC - это простой запрос (обычный оператор). В HQL, с другой стороны, есть параметр - так что он будет преобразован в JDBC PreparedStatement, и SQL для этого будет скомпилирован один раз, чтобы вы могли быстро запустить его, если вызываете его несколько раз, и передавать различные значения переменных,

Если вы выполните оба раза несколько раз, вы, вероятно, обнаружите, что запрос HQL будет в среднем быстрее, чем простой запрос JDBC.

Если вы просто выполните их один раз, то простая версия JDBC, вероятно, будет быстрее, чем HQL, поскольку изначально HQL будет скомпилирован.

Здесь есть некоторая интересная информация о Statement vs PreparedStatement:

http://oreilly.com/catalog/jorajdbc/chapter/ch19.html

Заявление против PreparedStatement

Существует распространенное мнение, что использование объекта PreparedStatement быстрее, чем использование объекта Statement. В конце концов, подготовленный оператор должен проверять свои метаданные в базе данных только один раз, тогда как оператор должен делать это каждый раз. Так как же это может быть иначе? Что ж, правда в том, что требуется около 65 итераций подготовленного оператора, прежде чем его общее время выполнения догоняет оператор. Это влияет на производительность вашего приложения, и этот вопрос посвящен исследованию этих проблем.

Когда дело доходит до того, какой объект оператора SQL работает лучше при обычном использовании, Statement или PreparedStatement, истина заключается в том, что объект Statement обеспечивает наилучшую производительность. Когда вы рассматриваете, как операторы SQL обычно используются в приложении -1 или 2 здесь, может быть, 10-20 (редко больше) на транзакцию - вы понимаете, что объект Statement будет выполнять их за меньшее время, чем объект PreparedStatement.

Ты можешь использовать session.createCriteria во избежание разбора HQL и сборки SQL.

Тем не менее, для сложных запросов проще просто заплатить небольшой штраф при первом попадании (хотя вряд ли это будет ~100 мс), чем создать сложный createCriteria состав.

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html

Другие вопросы по тегам