TGViewer
Spring АйО Spring АйО @spring_aio · 10.9K subscribers
Post #410 4.94K
⚠️ Spring Data: Page & Slice. Когда что использовать?

Отвечает эксперт сообщества Spring АйО – Михаил Поливаха.
–––
Есть один довольно маленький фикс, который Вы можете сделать в Spring Data, чтобы улучшить перформанс Ваших приложений, иногда заметно.

Не все знают, но пагинация бывает разная. Часто она нам нужна для того, чтобы не грузить все данные в память процесса. Ситуация схожая, если данные нужны front-end'у, и мы не хотим гонять огромные массивы данных по сети, front-end же в свою очередь будет рендерить их довольно долго, да и на практике так никто не делает. Чтобы адресовать подобные проблемы, мы используем пагинацию.

Возьмем Spring Data JPA (на самом деле неважно, какой именно модуль Spring Data вы тут возьмете, концепция везде едина). Предположим, что у нас есть сущность:


@Entity
public class SimpleEntity {
@Id
@Column(name = "id", nullable = false)
private Long id;
private String name;
private long createdAt;
// getters, setters, toString
}


и 2 метода в репозитории:


@Query("SELECT p FROM SimpleEntity p WHERE p.name LIKE :namePattern")
Slice<SimpleEntity> findCustomSlice(Pageable pageable, @Param("namePattern") String namePattern);
@Query("SELECT p FROM SimpleEntity p WHERE p.name LIKE :namePattern")
Page<SimpleEntity> findCustomPage(Pageable pageable, @Param("namePattern") String namePattern);


Они отличаются лишь типом возвращаемого значения. В первом случае - Slice, во втором - Page. Если вызвать первый метод, возвращающий Slice, то выполнится вот такой запрос (в общем случае):


select
se1_0.id,
se1_0.created_at,
se1_0.name
from
simple_entity se1_0
where
se1_0.name like ? escape ''
order by
se1_0.id
offset
? rows
fetch
first ? rows only


Но чаще всего люди используют Page. В этом случае Spring Data пошлёт запрос описанный выше и, вдобавок, ещё один запрос:


select
count(se1_0.id)
from
simple_entity se1_0
where
se1_0.name like ? escape ''


– Slice в Spring Data, как абстракция, представляет собой некоторую часть данных из общего датасета, некоторую страничку. Но эта страничка не знает о том, сколько всего страниц существует. Она знает свой порядковый номер, но она не знает, сколько страниц ещё впереди.
– Page расширяет понятие Slice, добавляя при этом страничке понимание того, а сколько страниц впереди неё, и сколько всего страниц в выборке. Для того, чтобы это понять, и нужен второй count() запрос.

Вывод

Если Вам не нужно знать общее количество страниц в выборке, то используйте Slice - на каждый запрос за каждой страницей вы сэкономите один count запрос.

Если вам нужно знать общее количество страниц в выборке (оно, скорее всего, не меняется, пока пользователь листает страницы, хотя имейте это в виду), то вы можете один раз отправить на front-end результат выполнения запроса с count() и дальше использовать Slice. Реализовать это можно по-разному.

❗️ Подробнее, как ещё можно оптимизировать постраничную навигацию, вы можете узнать в докладе экспертов сообщества (Ильи и Фёдора Сазоновых) на Jpoint 2023.
  • 👍 63
  • 🔥 20
  • 🤯 7
  • ❤ 1
More from @spring_aio
  1. Oct 11, 2026🎬 Записи докладов с JPoint 2026 уже в открытом доступе JUG Ru Group выложили записи с про…
  2. Oct 9, 2026👩‍💻 Kotlin получил почти настоящие статики Начиная с Kotlin 2.5.0-Beta1 можно эксперимен…
  3. Oct 8, 2026🍃 Spring Boot ломает совместимость, G1 тормозит микросервисы, Java долго релизит фичи | S…
  4. Oct 6, 2026👩‍💻 Spring Config Import без магии У наших друзей из Axelix вышла статья о том, как Spri…
  5. Oct 5, 2026🥲 В Java 27 TLS научился переживать квантовую атаку При установке HTTPS-соединения клиент…
  6. Oct 3, 2026⚡️⚡️Строки кода стремятся подешеветь до цены токена. Что остается ценным? Про это — трек «…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →