Что такое пагинация в контексте работы с базами данных?

«Что такое пагинация в контексте работы с базами данных?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Пагинация — это техника разделения большого результата SQL-запроса на дискретные страницы для постраничного вывода в UI (например, списка товаров, записей в логе).

Классический подход с LIMIT/OFFSET (MySQL/PostgreSQL):

// Параметры пагинации
$perPage = 20;
$currentPage = max(1, (int) ($_GET['page'] ?? 1));
$offset = ($currentPage - 1) * $perPage;

// Запрос с пагинацией. ВАЖНО: Используйте подготовленные выражения!
$stmt = $pdo->prepare("SELECT id, title, created_at FROM articles ORDER BY created_at DESC LIMIT :limit OFFSET :offset");
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$articles = $stmt->fetchAll();

// Подсчет общего количества страниц
$totalStmt = $pdo->query("SELECT COUNT(*) FROM articles");
$totalItems = $totalStmt->fetchColumn();
$totalPages = ceil($totalItems / $perPage);

Проблемы и улучшения:

  • OFFSET на больших страницах медленный, так как БД должна «пропустить» N записей. Решение — keyset pagination (курсорная).
  • Keyset Pagination (быстрее для бесконечной прокрутки):
    -- Вместо OFFSET 10000, LIMIT 20
    -- Используем условие по последнему полученному значению
    SELECT * FROM articles
    WHERE created_at < '2023-10-01 00:00:00' -- Значение с предыдущей страницы
    ORDER BY created_at DESC
    LIMIT 20;
  • Пагинация должна быть частью API-ответа: { "data": [...], "meta": { "current_page": 2, "total_pages": 50 } }.