EclipseLink генерирует декартовой план вместо (внутренних) объединений в SQL. Зачем? - PullRequest
5 голосов
/ 16 марта 2010

В проектах, где Hibernate является моим поставщиком персистентности, я могу создавать запросы с выражениями 'join fetch', а Hibernate генерирует SQL, который отражает: SQL, содержащий выражения объединения, с использованием допустимых путей сравнения.

EclipseLink, однако, выдает SQL с уродливыми декартовыми планами, которые сильно ухудшают производительность. Читая эту статью , в ней упоминается, что активная загрузка может привести к созданию картезианских планов, но при этом удобно забыть, что другие провайдеры (Hibernate) могут оптимизировать это.

Итак, можно ли поручить EclipseLink оптимизировать эти запросы? Я полагаю, что с помощью аннотации @FetchJoin можно оптимизировать несколько отношений, но я надеюсь найти что-то, что не включает распространение аннотаций, специфичных для ORM, в модели предметной области.

В качестве примера вот (динамический) запрос, который я выдаю как JPQL:

String query = "select w from WorkOrder w " +
            "inner join fetch w.type " +
            "inner join fetch w.details " +
            "inner join fetch w.project " +
            "inner join fetch w.priority " +
            "inner join fetch w.networkElement ";

А вот вывод EclipseLink:

SELECT t1.ID, t1.CREATION, ... (the fetch fields here)
FROM swa_network_element t5, swa_priorities t4, swa_dispatch_project t3, swa_work_order_detail t2, swa_work_orders t1, swa_work_order_type t0
WHERE ((t1.alpha_id LIKE '%TSK%') AND (((((t0.ID = t1.TYPE_ID) AND (t2.worder_id = t1.ID)) AND (t3.id = t1.project_id)) AND (t4.ID = t1.priority_id)) AND (t5.ID = t1.ne_id))) ORDER BY t1.CREATION DESC

С наилучшими пожеланиями, Родриго Хартманн

Ответы [ 2 ]

3 голосов
/ 22 февраля 2011

Попробуйте использовать:

@org.eclipse.persistence.annotations.JoinFetch(JoinFetchType.INNER)

- или -

@org.eclipse.persistence.annotations.JoinFetch(JoinFetchType.OUTER)

Наружные объединения рекомендуются для столбцов, допускающих значение NULL.

В этом блоге я нашел больше информации: http://vard -lokkur.blogspot.com / 2010/09 / jpa-demysified-episode-1-onetomany-and.html

С уважением,

Виктор Торторелло Нето

0 голосов
/ 01 августа 2012

Я не уверен, что вы имеете в виду? SQL кажется правильным, есть объединение для каждой таблицы, в какой таблице отсутствует объединение?

Какой SQL вы ожидаете?

Если вы хотите поместить условие соединения в предложение FROM вместо предложения WHERE, EclipseLink делает это для внешних объединений, как это требуется, но не для внутренних объединений, поскольку это не имеет значения для любой базы данных, о которой мне известно , Если вы действительно этого хотите, вы можете настроить EclipseLink 2.4 для печати условия соединения для внутренних объединений в предложении FROM с помощью API-интерфейса DatabasePlatform setPrintInnerJoinInWhereClause (false), но это не должно влиять на действия базы данных.

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

См http://java -persistence-performance.blogspot.com / 2010/08 / партии сгрузить-оптимизации объектно-graph.html

...