HQL присоединился к запросу, чтобы получить большое количество связей
Недавно мой проект обнаружил, что Hibernate может принимать несколько уровней отношений и получать их в одном соединении HQL для создания заполненного объекта, который нам нужен. Мы любим эту функцию, полагая, что она превзойдет ситуацию с ленивым приложением.
Проблема заключается в том, что мы сталкиваемся с ситуацией, когда у одного родителя имеется около дюжины прямых отношений, из-за чего есть несколько подзадач, и некоторые из них имеют несколько десятков строк в нескольких случаях. В результате получается довольно большой кросс-продукт, который приводит к тому, что hql вращается вокруг колес практически навсегда. Мы добрались до 11 и увидели более 100000 итераций, прежде чем мы сдались и убили.
Так ясно, хотя эта техника отлично подходит для некоторых ситуаций, она имеет ограничения, как и все в жизни. Но какова самая эффективная альтернатива в спячке для этого? Мы не хотим лениво загружать их, потому что мы столкнемся с ситуацией N + 1, которая будет еще хуже.
- вектор или карту, какой из них использовать?
- Получение итогового количества строк из OFFSET / FETCH NEXT
- Производительность dynamic_cast?
- Java: двумерный массив хранится в порядке столбцов или строк?
- Каков самый быстрый способ обмена значениями в C?
В идеале я хотел бы, чтобы Hibernate предварительно извлекал все строки и детали, но делал это по одной связи за раз, а затем убирал нужный объект с нужным родителем, но я понятия не имею, делает ли это что-то подобное.
Предложения?
ОБНОВИТЬ:
Таким образом, мы получили SQL-запрос, созданный этим запросом, оказалось, что я неправильно диагностировал проблему. Кросс-продукт НЕ такой огромный. Мы выполнили тот же запрос в нашей базе данных напрямую и получили 500 строк, возвращенных всего за секунду.
Тем не менее, мы очень четко видели в журнале спящего режима, что он делал итерации 100 КБ. Возможно ли, что Hibernate может попасть в цикл в ваших отношениях или что-то еще?
Или, может быть, это нужно задать в качестве нового вопроса?
- Создание m различных случайных чисел в диапазоне
- '...! = Null' или 'null! = ...' лучшая производительность?
- MongoDB 'count ()' очень медленный. Как мы усовершенствуем / работаем с ним?
- Количество разделов в RDD и производительность в Spark
- Рисование поэтапно в UIView (iPhone)
- Есть ли разница в производительности между циклами for и циклом for-each?
- Быстрое векторное rsqrt и обратное с SSE / AVX в зависимости от точности
- Производительность бритвы ASP.NET MVC 3
Наша команда использует специальную страtagsю для работы с ассоциациями. Коллекции ленивы, отдельные отношения тоже ленивы, кроме ссылок с простой структурой (например, ссылка на страны). И мы используем свободно-hibernate для загрузки того, что нам нужно в конкретной ситуации. Это просто из-за того, что fluent-hibernate поддерживает вложенные проекции. Вы можете обратиться к этому модульному тесту, чтобы узнать, как может быть частично загружена grid объектов. Фрагмент кода из модульного теста
List roots = H. request(Root.class).proj(Root.ROOT_NAME) .innerJoin("stationarFrom.stationar", "stationar") .proj("stationar.name", "stationarFrom.stationar.name") .eq(Root.ROOT_NAME, rootName).transform(Root.class).list();
Смотрите также
Как преобразовать плоский результирующий набор, используя Hibernate