オフセットベースのページネーション
TL; DR
OFFSETとLIMITをページ識別子として使う。
Pros
実装が簡単
「n番目のページ」のようなページ識別子が作れるので、いきなりnページ目に飛ばしたりできる
Cons
ページネーションの対象となるテーブルが大量のデータを持っているとき、性能が劣化する
ページをめくっている最中に、先頭にデータが追加されると内容がズレる
説明
例えば、以下のような tweets テーブルがあるとする。
code:sql
CREATE TABLE tweets (
id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY,
text TEXT NOT NULL,
)
このテーブルを 10件づつページネーションする場合、以下のようなクエリを打つ。
code:sql
-- 1ページ目
SELECT * FROM tweets
ORDER BY id -- id はプライマリーキーなので、ORDER BYが高速にできる
LIMIT 10
-- 2ページ目
SELECT * FROM tweets
ORDER BY id
OFFSET 10
LIMIT 10
-- 3ページ目
SELECT * FROM tweets
ORDER BY id
OFFSET 20
LIMIT 10
...
これが、オフセットベースのページネーションである。
この形式のページネーションは実装が簡単で、かつ「nページ目」のようなページ識別子が作れるので便利である。
一方で、クエリにOFFSETを指定した場合は内部的に、OFFSET件数だけデータ取得した上で読み飛ばすという処理が行われる。そのため、OFFSETに指定する数字が大きくなればなるほど性能は劣化してしまう。
ただし、「実際問題としては先頭のページしか閲覧されない」というような仮定を置けるのであれば、OFFSETの性能劣化を気にする必要がないこともある。