Переписать JPA-запрос для повышения производительности

#java #spring #jpa #spring-data-jpa

#java #весна #jpa #spring-data-jpa

Вопрос:

У меня есть 2 объекта: parent (id integer, ...) и child(id integer, parent_id integer, ...)
У меня есть спецификация JPA, которая строит запрос в методе toPredicate(Root<Child> root, CriteriaQuery<?> query, CriteriaBuilder cb) . Этот запрос выглядит следующим образом

 select ch.*
   from child ch
      inner join parent pr on ch.parent_id = pr.id
   where ch.field1 = ?
     and ch.field2 = ?
     and pr.field1 = ?
     ... other simple conditions
  order by field
  limit 50 offset 750000
 

Этот запрос работает 18 секунд, индекс не работает. Но я запускаю sql-запрос, как

 select ch.*
   from (select * 
         from child
         where ch.field1 = ?
           and ch.field2 = ?
           and ...) as ch
      inner join (select * 
                  from parent 
                  where pr.field1 = ? 
                    and ...) pr on ch.parent_id = pr.id
   where 
    ... other simple conditions
  order by field
  limit 50 offset 750000
 

Этот запрос выполняется 3 секунды.

Вопрос:
Могу ли я реализовать второй запрос в методе toPredicate(...) ?

Окружающая среда

  • PostgreSQL 9.6
  • Spring Data JPA 1.11.11.ВЫПУСК
  • Весна 4.3.16.ВЫПУСК
  • Гибернация 5.2.2.Финал

Комментарии:

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