Производительность Oracle JPA с данными Spring с разбивкой на страницы

Я хочу получить большой набор данных с JpaRepository, поддерживаемый таблицей Oracle. Возможен выбор: вернуть коллекцию (List) или Page объекта, а затем просмотреть результаты. Обратите внимание: я должен использовать каждую запись в этом наборе ровно один раз. Это не "поиск-первый-из-большого-набора-и-возврата" операция.

Хотя идея разбиения на страницы привлекательна, производительность будет ужасной (n ^ 2), потому что для каждой запрашиваемой страницы oracle должен будет открывать предыдущие n-1 страницы, что постепенно ухудшает производительность по мере того, как я углубляюсь в набор результатов.

Насколько я понимаю, альтернатива List состоит в том, что весь набор результатов будет загружен в память. Для Oracle JPA spring не имеет набора результатов поддержки.

Итак, вот мои вопросы

  1. Правильно ли я понимаю, как List работает с данными Spring? Если это не так, я просто использую List.
  2. Если я прав, есть ли альтернатива потокам наборов результатов Oracle / JPA?
  3. Есть ли третий способ, о котором я не знаю.

person Prashant    schedule 29.06.2017    source источник
comment
Не используйте слой обфускации (он же ORM). Используйте простой JDBC и перебирайте ResultSet - тогда нет необходимости хранить что-либо еще, кроме текущей строки в памяти.   -  person a_horse_with_no_name    schedule 29.06.2017
comment
@a_horse_with_no_name, спасибо. Я могу использовать JDBC с набором результатов только вперед, но я бы предпочел альтернативу, использующую Spring Data, поскольку это то, что использует остальная часть проекта.   -  person Prashant    schedule 29.06.2017
comment
Если вам нужна производительность и эффективность (памяти), тогда нет альтернативы прямому вызову JDBC.   -  person a_horse_with_no_name    schedule 29.06.2017
comment
Я согласен с @a_horse_with_no_name, и вы можете пройти через JPA, используя именованные запросы docs.spring.io/spring-data/jpa/docs/current/reference/html/   -  person Rafik BELDI    schedule 29.06.2017


Ответы (1)


Страничные методы в SDJ вызывают дополнительные select count(*) from ... при каждом запросе. Думаю, в этом причина проблемы. Чтобы избежать этого, вы можете использовать Slice вместо Page в качестве возвращаемого параметра, например:

Slice<User> getAllBy(Pageable pageable);

Или вы можете использовать даже List сущностей с разбивкой на страницы:

List<User> getAllBy(Pageable pageable);

Дополнительная информация

person Cepr0    schedule 30.06.2017