Laravel カーソルページングを試してみる
本題
Laravel Ver.8.41(2021年5月)より、カーソルページング機能が追加されています。
これは何かという話は、詳しくは、ドキュメントやプルリクを参照いただきたいのですが、
https://readouble.com/laravel/8.x/ja/pagination.html#cursor-pagination
https://github.com/laravel/framework/pull/37216
利点としては、OFFSETなどの場合と比較して、データが追加・削除等されても、抜けが発生しなかったり、また、INDEXを張ったキーでソートすれば、パフォーマンスが向上するという事です。(一説では、OFFSET 100000 だと、最大400倍速いとか)
但し、いつもの paginate() の時のように、1 2 3 4 5 ... の数字番号は付きません。また、URLは以下の感じになるので、現在何ページ目なのかは見ても分かりません。
/?cursor=eyJpZCI6MjkxLCJfcG9pbnRzVG9OZXh0SXRlbXMiOnRydWV9
ただ、そういうのが不要な場合、特に無限スクロールなどで、利用価値がありそうです。
という事で、以下の感じで試してみました。
Route::get('/', function () {
$users = User::query()
->orderByDesc('id')
->cursorPaginate(10);
return view('welcome', compact('users'));
});
すると、次を押した後のURLは、以下のようになりました。
/?cursor=eyJpZCI6MjkxLCJfcG9pbnRzVG9OZXh0SXRlbXMiOnRydWV9
で、この時発行された SQL は、以下の感じです。
select * from `users` where (`id` < 291) order by `id` desc limit 11
いや、なんか凄いですね。
ちなみに、Lavel Livewire でも
数日前にリリースされた Lavel Livewire v2.8.2 でも、カーソルページングの対応がされました。
[Feature] Add cursor pagination to Livewire #3215
Laravel と Livewire が共に対応していれば、同じ感じで行けます。
public function render()
{
$users = User::query()
->orderByDesc('id')
->cursorPaginate(10); // ← ここ
return view('livewire.show-users', [
'users' => $users,
]);
}
ただ、デフォルトの Tailwind CSS テーマでは問題ありませんが、Bootstrap テーマを使用すると、ちょっとまだバグってエラーとなる状態です。 次のバージョンで直ります。 Fix cursor pagination in bootstrap #4406
雑感
今後、場面に応じて使って行こうと思います。
おかしな箇所等ありましたらコメント下さい。
Discussion