Собственные запросы JPA по сравнению с «чистой» устойчивостью JPA - PullRequest
2 голосов
/ 30 июля 2011

У меня есть сценарий, в котором мне нужно вести журнал всех входящих файлов (flat, xml) для приложения. Эта таблица журнала практически не используется, за исключением случаев расследования неисправностей или целей регулирования и тому подобного, и данные будут регулярно удаляться.

Мы используем JPA 2.0 для постоянства. Мы попробовали первоначальный прототип с чистым постоянством JPA, используя entityManager.persist(); и flush немедленно. Но производительность не оправдала ожиданий. Поэтому я предложил NativeNamedQueries для этой операции, и улучшение производительности было огромным (300 миллисекунд против 47 миллисекунд) в тестах.

Но ведущий инженер немного непреклонен в использовании NativeNamedQueries, говоря, что он связан с базой данных и менее удобен в обслуживании и тому подобное.

Вопросы:

  1. Как вы к этому относитесь, если вам нужно было принять решение? Как часто происходят изменения базы данных или схемы после запуска приложения?

  2. Есть ли другой способ улучшить производительность? Производительность очень и очень важна для этого приложения.

Прошло всего 4 года с тех пор, как я начал программировать, но никогда не видел изменения схемы БД или изменения поставщика БД для существующего приложения.

Примечание. Мы используем EclipseLink 2.3 и Oracle. Также это свежее приложение, которое мы разрабатываем. На всякий случай эти пункты проясняют вопрос

Ответы [ 3 ]

4 голосов
/ 30 июля 2011

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

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

Если вы пишете типичное бизнес-приложение, яможно ожидать, что какая-то форма кругового проектирования между объектной моделью и моделью базы данных возникнет в процессе разработки.Ваши администраторы баз данных должны владеть и хорошо знать модель базы данных, чтобы они могли помочь или выполнить точную настройку запросов, выдаваемых вашей средой ORM.При этом следует помнить, что вы не можете полагаться только на запросы, выданные платформой ORM.Все изменения должны быть предпочтительно выполнены и протестированы в средах разработки и тестирования интеграции (и, возможно, UAT, если у вас есть) перед его развертыванием в производстве, и, как подсказывает здравый смысл, все изменения будут находиться под контролем версий.

Что касается привязки запросов к базе данных, то это решение, которое должен принять ваш бизнес.Если вы поддерживаете несколько баз данных, вам следует протестировать против всех.Кроме того, вы должны иметь возможность предоставлять разные дистрибутивы для поддержки разных баз данных;это станет проще, если вы поместите свои собственные запросы в специфичные для базы данных файлы orm.xml, такие как orm-oracle.xml, orm-mysql.xml и т. д., и переименуете файлы в orm.xml перед подготовкой распространения.Использование Maven или Ant сделает предлагаемое изменение простым для реализации.

Есть ли другой способ повысить производительность?Производительность очень важна для этого приложения.

Это будет зависеть от того, насколько хорошо вы спроектировали свои объекты и модели данных, насколько хорошо вы понимали свою среду ORM и насколько вы готовы к "коррупции""Ваша объектная модель.

Первый шаг настройки производительности любого приложения - всегда измерять дважды и сокращать один раз.Вы не можете просто перебрать список возможных решений и попробовать каждое из них, не зная, как они работают и в каких обстоятельствах они полезны;хорошо, вы могли бы сделать это, если ваш бизнес готов тратить на это время, но это часто не так.

Для начала вам нужно понять, почему собственные запросы предоставляют или появляются *, чтобы обеспечить лучшую производительность.Возможно, это во многом связано с тем, что вы просто вставляете данные, и для среды ORM было бы лучше просто выполнить оператор INSERT, а не создавать его из HQL или абстрактной нотации запросов, используемой под капотом.;только профилировщик покажет разницу.

Если вышеприведенное верно, то вы могли бы пересмотреть, должны ли ваши таблицы аудита управляться средой ORM.Если ваше приложение отвечает только за запись в эти таблицы, а не за чтение из них (и вполне возможно, что другое приложение отвечает за чтение записей), то я подозреваю, что отсутствие управления этими таблицами в ORM обеспечит лучшую производительность, особенноесли вы используете простой JDBC для выдачи оператора INSERT.Причина довольно проста - если ваша структура ORM управляет сущностью, то она также отвечает за управление контекстом постоянства (который теперь включает в себя класс и связанную таблицу);отсутствие управления ORM для объекта возможно приведет к сценарию, в котором контекст постоянства вообще не нужно обновлять для записей аудита.

Существует здоровая возможность других мер настройки производительности, которые выможет предпринять, но, как я уже говорил ранее, это потребует от вас понимания отчета профилировщика и оценки того, какие возможные варианты будут лучше в вашем приложении.

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

2 голосов
/ 30 июля 2011
  1. Довольно редко вы действительно DO переключаете провайдера базы данных, особенно после того, как вы заплатили несколько сотен тысяч лицензий за отличную и высокопроизводительную базу данных, такую ​​как Oracle. Кроме того, варианты синтаксиса SQL оператора INSERT не настолько различны, что вы не сможете переключать базу данных, даже при использовании собственного SQL, исключительно.

  2. Я не понимаю, почему исправление одного запроса, требующего дополнительной настройки, плохо. Спросите своего ведущего разработчика, почему он так строг. Но прежде чем вы это сделаете, используйте профилировщик, такой как JProfiler или Yourkit, чтобы определить точное место, которое вызывает проблемы с производительностью. В JPA любой из этих факторов может вызвать проблемы: кеширование, активная загрузка зависимых данных (которые вам, вероятно, не понадобятся), неэффективная генерация SQL, неправильный план выполнения запросов в вашей базе данных Oracle и т. Д. в конце концов, мне нужен собственный запрос.

  3. Если производительность настолько критична, то, возможно, JPA недостаточно хорош для работы. Рассматривали ли вы (и ваш ведущий разработчик) другие инфраструктуры, такие как jOOQ , QueryDSL , MyBatis или что-то подобное? Из ваших комментариев я понял, что ваши основные сценарии использования - это OLAP-запросы, а не OLTP, поэтому вам может даже потребоваться использовать расширенные функции Oracle, такие как аналитические функции и функции хранилища данных, для которых jOOQ имеет встроенную поддержку, для экземпляр ...

1 голос
/ 30 июля 2011

1) Я видел только 2 приложения, которые перешли с oracle на MySQL (чтобы сэкономить на стоимости лицензий) за 10 лет, так что это случается не очень часто, НО, если вы хотите написать интеграционные тесты с использованием другой базы данных (например,hsqldb) у вас будут проблемы.

О том, как часто меняется схема после запуска приложения, мой ответ: МНОГО !!Если приложение будет регулярно обновляться, ожидайте МНОГО изменений, так как обычно команда лучше понимает бизнес.Я даже работал над проектом, в котором схема значительно изменилась после одного года запуска приложения.

В то же время, похоже, что вы отложили оптимизацию до последнего возможного времени (хорошая вещь дляделать) и теперь вам нужно оптимизировать sql с помощью некоторых собственных запросов (что также происходит довольно регулярно) ... Я хочу сказать, что ваша идея совсем не звучит плохо для меня.

2) В прошлом я использовал смесь Hibernate и iBatis (или mybatis в настоящее время) для аналогичных ситуаций (на случай, если вы захотите проверить iBatis).И один вопрос, почему вы делаете flush () после каждого persist ()?Вам не нужно этого делать.

Кроме того, я весьма удивлен, что вставки занимают намного больше времени, если они выполняются в EclipseLink.Вызовы persist () должны занимать почти столько же времени, сколько и нативный запрос (я предполагаю, что они будут дольше, если есть какие-либо обратные вызовы жизненного цикла).Я предполагаю, что вы видели sql, сгенерированный eclipseLink, он отличается?

Я знаю, что мой ответ совсем не конкретен, но я надеюсь, что это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...