TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #577 15.2K
Как быстро отдавать данные по частям

Пагинация с первого взгляда кажется простой задачей. На практике это та ещё кроличья нора🌚

В этом посте расскажу 2 подхода к пагинации со стороны SQL, их плюсы, минусы и основные кейсы. За кадром оставим нюансы спринга и хибернейта.

Итак, пагинация бывает двух видов: offset и keyset.

🌸 Offset - для получения части данных используется (сюрприз) оператор offset. Первую страницу получаем так:
SELECT * FROM t ORDER BY …
LIMIT 100

Для второй и последующих добавляем offset:
SELECT * FROM t ORDER BY …
LIMIT 100 OFFSET 100

Offset показывает, сколько строк пропустить.

В чем подвох: кажется, что при offset 100 постгрес сразу прыгнет на 101 строку, но это не так. Он честно пройдет 100 строк, и потом отдаст следующие 100.

❌ В случае большого оффсета такая операция будет работать долго даже при наличии индекса
✅ Просто реализовать. Минимум действий со стороны клиента и поддержка в фреймворках.

🌸 Keyset пагинация. Она же cursor, она же seek.

Здесь мы используем where в паре с индексом и сразу прыгаем на нужную позицию. Первую страницу получаем так:
SELECT * FROM t ORDER BY name
LIMIT 10

Если записи отсортированы по имени, запоминаем имя последнего элемента. Пусть это будет х. Чтобы получить вторую страницу, добавляем where:
SELECT * FROM t ORDER BY name
WHERE name > x
LIMIT 10

✅ Работает быстрее, чем вариант с оффсетом. Чем больше оффсет, тем значительнее разница
❌ Сложнее в реализации, надо запоминать поле в последней пачке
❌ Нельзя перейти к произвольной странице, только последовательная выдача данных

Когда что использовать?

Во многих докладах/статьях часто встречается мысль, что оффсет это ужас, и надо всегда использовать кейсет. На практике все не так категорично:

▫️ Если на сайте infinite scrolling или пользователь вряд ли будет много смотреть, вполне ок использовать простую оффсет пагинацию.

▫️ Если данные выкачиваются большими пачками для обработки, аналитики, миграции и тд, берём keyset пагинацию.

▫️ Если надо выгрузить много данных и прыгать по ним туда-сюда или у вас другой сложный случай, придется экспериментировать с индексами и запросами. Этот доклад хорошо показывает, что пагинация - далеко не тривиальная задача.

А поставить огонек качественному контенту очень просто, поэтому это нужно обязательно сделать🔥
  • 🔥 625
  • 👍 47
  • ❤ 24
  • 👎 7
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
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 →