TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2749 2.85K
День 2276. #ЗаметкиНаПолях
Разбираем Курсорную Пагинацию. Начало
Пагинация (разбиение на страницы) имеет решающее значение для эффективной доставки больших наборов данных. Хотя офсетная пагинация (offset pagination) широко используется, курсорная пагинация (cursor pagination) предлагает некоторые интересные преимущества для определённых сценариев. Она особенно ценна для каналов в реальном времени, интерфейсов бесконечной прокрутки и API, где производительность имеет значение в масштабе, например, для журналов активности или потоков событий, где пользователи часто просматривают большие наборы данных. Рассмотрим детали реализации и обсудим, где каждый подход имеет наибольший смысл.

Создадим простое хранилище записей пользователя с помощью следующего объекта:
public record UserNote (
Guid Id,
Guid UserId,
string? Note,
DateOnly Date
);


Традиционный подход: Офсетная пагинация
Офсетная пагинация использует Skip и Take. Мы пропускаем определённое количество строк и берём фиксированное количество строк. Обычно они преобразуются в OFFSET и LIMIT в запросах SQL:
var query = dbContext.UserNotes
.OrderByDescending(x => x.Date)
.ThenByDescending(x => x.Id);

// При офсетной пагинации мы обычно сначала считаем общее количество элементов
var total = await query
.CountAsync(cancellationToken);
var pages = (int)Math.Ceiling(total / (double)pageSize);

var query = dbContext.UserNotes
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync(cancellationToken);

Заметьте, что мы сортируем результаты по дате и Id в обратном порядке. Это обеспечивает единообразие результатов при разбиении на страницы. Вот сгенерированный SQL (в PostgreSql) для офсетной пагинации:
// запрос общего количества
SELECT count(*)::int FROM user_notes AS u;

// запрос данных
SELECT u.id, u.date, u.note, u.user_id
FROM user_notes AS u
ORDER BY u.date DESC, u.id DESC
LIMIT @pageSize OFFSET @offset;


Ограничения офсетной пагинации:
- Производительность ухудшается по мере увеличения смещения, поскольку база данных должна сканировать и отбрасывать все строки до параметра OFFSET;
- Риск потери или дублирования элементов при изменении данных между страницами;
- Несогласованные результаты при одновременных обновлениях.

Продолжение следует…

Источник:
https://www.milanjovanovic.tech/blog/understanding-cursor-pagination-and-why-its-so-fast-deep-dive
  • 👍 15
More from @netdeveloperdiary
  1. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  2. Oct 3, 2026Post #3360
  3. Oct 3, 2026День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую…
  4. Oct 2, 2026День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пос…
  5. Oct 1, 2026Post #3357
  6. Sep 30, 2026Post #3356
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 →