NHibernate HQL против CriteriaAPI против QueryOver vs Linq. Представление
Каковы различия производительности между hql и criteriaApi и QueryOver? Существуют ли ситуации, когда один быстрее или медленнее, чем другой?
Изменить: я продлил вопрос с QueryOver и Linq.
=============================================
Ну, я не уверен, какой ответ на отметку как ответ, поэтому я буду отмечать сообщения с большинством VoteUp. Я не знаю. Это скорее обсуждение, чем вопрос.
Ответы
Ответ 1
Характеристики производительности между ICriteria и HQL незначительно меняются (я не знаю о QueryOver) по одной простой причине.
Запросы ICriteria по умолчанию попытаются реализовать ваши стратегии выборки, как определено в вашем сопоставлении, тогда как HQL по умолчанию считает все Lazy и зависит от ваших объявлений о присоединении внутри вашего запроса, чтобы определить, что с нетерпением вывешено или нет.
Дополнительно ICriteria зависит от сопоставления для передачи параметров, тогда как HQL допускает явные типы параметров, например. IQuery.SetInt32 ( "fooParam", 5);
Что действительно важно, так это возможность подключения ICriteria-запросов (см. ICriteria.CreateCriteria(). CreateCriteria() и т.д.), где движку NH придется разрешить ICriteria и попытаться сгенерировать наиболее достоверный SQL.
В противоположной стороне, вероятно, легче предсказать, приведет ли запрос HQL к согласованным результатам и, как таковое, упростит использование QueryCache.
В любом случае конфигурация создается один раз с определениями создания и сопоставления ISessionFactory и что-то не в памяти, поэтому производительность хорошая.
Фактическая генерация SQL производится по-разному между двумя, и именно по этой причине утилита для ICriteria → HQL не существует.
В конце концов, мой опыт показал мне, что производительность между 2, вероятно, одинаково дает или занимает несколько миллисекунд.
В качестве побочного примечания, объявление максимально возможного в сопоставлении приведет к более сжатию генерации sql, а также к действию NHibernate, например, для свойств строк, отображающих Length
в .hbm.xml, приведет к проверке NHibernate длины строк перед переходом в базу данных.
Ответ 2
Что касается QueryOver, я бы ожидал, что производительность будет идентичной API-интерфейсу Criteria, поскольку она построена как расширение этого API. Поэтому для эквивалентных запросов в двух API-интерфейсах я ожидаю, что будет создан тот же запрос к базе данных. Единственное различие, которое я заметил между интерфейсами QueryOver и Criteria, заключается в том, что я считаю интерфейс QueryOver более "чистым" и более приятным для работы.
По моему опыту API-интерфейс Criteria получил больше "любви", чем интерфейс HQL. Я столкнулся с ситуациями, когда я мог бы выражать определенные запросы с помощью интерфейса критериев, что я не мог найти эквивалентный способ выражения в интерфейсе HQL.
Что касается производительности, я нахожу, что запрос "спросил" больше влияет на производительность, чем на выбор API критериев по сравнению с HQL и QueryOver. Я бы использовал интерфейс, который обеспечит вам наиболее естественную форму вашего мышления.
Ответ 3
QueryOver является очень хорошей заменой критериям в большинстве случаев из-за улучшенного синтаксиса и безопасности типов. Однако следует отметить, что обработка лямбда-выражений в QueryOver может быть дорогостоящей (и я думаю, что то же самое применимо к запросам LINQ). Поэтому при выполнении конечного SQL-запроса не требуется больше, чем другие методы (ICriteria, HQL), преобразование объекта запроса в соответствующий SQL-запрос занимает больше времени.
В качестве примера мы разработали приложение, в котором выполнялось сотни запросов QueryOver (с поддержкой пакетной поддержки ADO.NET), и мы обнаружили, что преобразование запросов в ICriteria почти удвоило нашу способность выполнять запросы и уменьшило вдвое потребление ЦП, Я предполагаю, что накладные расходы, связанные с обработкой выражения лямбда, могут быть значительно уменьшены, если вы используете кэширование второго уровня и кеширование запросов; но поскольку это не подходит для нашего приложения, я не сделал этого сам.
Относительно вашего более общего вопроса о том, что происходит быстрее: это действительно зависит. Единственный верный способ сказать - запустить инструмент профилирования (NHProf творит чудеса для таких сценариев, как это). Но, вообще говоря, HQL является наиболее близким к SQL и, следовательно, наиболее гибким, что позволяет вам немного расширить возможности для оптимизации ваших запросов. Однако для подавляющего большинства запросов простой и промежуточной сложности между ICriteria и HQL практически нет никакой разницы. Запросы ICriteria намного проще работать, если ваши запросы динамически построены.
Ответ 4
Мне еще предстоит найти разницу между ними. Это говорит о том, что hql имеет функциональность, недоступную в Criteria-API.
В основном это вопрос стиля и личных предпочтений, если вы используете первый или последний. И перевод с вашего запроса на SQL не учитывает многое, когда дело доходит до запросов.
От людей, которые знают больше, чем я: http://ayende.com/Blog/archive/2009/06/01/nhibernate-queries-ndash-should-i-use-hql-or-criteria.aspx