Курсорная пагинация
Ваш запрос должен содержать выражение order by
, чтобы можно было использовать курсорную пагинацию
.
В то время как paginate
и simplePaginate
создают запросы с использованием выражения offset
SQL. Курсорная пагинация работает путем создания выражений where
, которые сравнивают значения упорядоченных столбцов запроса, обеспечивая наиболее эффективную производительность базы данных среди всех возможных методов пагинации в Laravel. Этот метод пагинации особенно хорошо подходит для больших наборов данных и пользовательских интерфейсов с бесконечной
прокруткой.
В отличие от пагинации на основе смещения, которая включает номер страницы в строке запроса URL-адресов, сгенерированных пагинатором, курсорная пагинация помещает строку «курсора» в строку запроса. Курсор представляет собой закодированную строку, содержащую текущее положение, с которого следующий запрос пагинации должен начать постраничную разбивку, и направление, в котором она должна выполняться:
http://имя_домена.ru/users?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0
Вы можете создать экземпляр пагинатора на основе курсора с помощью метода cursorPaginate
построителя запросов. Этот метод возвращает экземпляр Illuminate\Pagination\CursorPaginator
:
App/Http/Controllers/UserController.php<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
class UserController extends Controller
{
public function index()
{
return view('user.index', [
$users = DB::table('users')->orderBy('id')->cursorPaginate(15);
]);
}
}
После того, как вы получили экземпляр курсора, вы можете отобразить результаты постраничной навигации, как и обычно при использовании методов paginate
и simplePaginate
.
Отличия курсорной пагинации и на основе смещения
Чтобы проиллюстрировать различия между этими постраничными разбивками, давайте рассмотрим несколько примеров запросов SQL. Оба следующих запроса будут отображать «вторую страницу» результатов для таблицы users
, упорядоченных по id
:
# Пагинация на основе смещения ...
select * from users order by id asc limit 15 offset 15;
# Курсорная пагинация ...
select * from users where id > 15 order by id asc limit 15;
Запрос курсорной разбивки предлагает следующие преимущества по сравнению со смещенной разбивкой:
- Для больших наборов данных курсорная разбивка будет обеспечивать лучшую производительность, если столбцы, по которым выполняется упорядочение
order by
индексируются. Это связано с тем, что выражениеoffset
сканирует все ранее сопоставленные данные. - Для наборов данных с частой записью при разбивке на основе смещения могут быть пропущены записи или показаны дубликаты, если результаты были недавно добавлены / удалены со страницы, которую пользователь просматривает в данный момент.
Однако курсорная пагинация имеет следующие ограничения:
- Как и
simplePaginate
, курсорная пагинация может использоваться только для отображения ссылок «Далее» и «Назад» и не поддерживает создание ссылок с номерами страниц. - Требуется, чтобы порядок был основан как минимум на одном уникальном столбце или уникальной комбинации столбцов. Столбцы со значениями
null
не поддерживаются. - Выражения запроса в конструкциях
order by
поддерживаются только в том случае, если они имеют псевдонимы и добавлены в конструкциюselect
.