CodeGym /コース /SQL SELF /OFFSETを使った行のスキップとページネーションの作り方

OFFSETを使った行のスキップとページネーションの作り方

SQL SELF
レベル 3 , レッスン 1
使用可能

ちょっと質問!ネットショップのサイトで1ページに商品が多すぎるとき、どうする?そう、次のページを開くよね。じゃあ、その裏側で何が起きてるか知ってる?そこではSQLの魔法が動いてて、OFFSETコマンドで行をスキップしてるんだ。今日はOFFSETって何か、何のために使うのか、どうやって使うのか、そしてなぜデータのページネーションの基本なのかを説明するよ。

OFFSETはSQLのキーワードで、クエリの結果から指定した数だけ行をスキップできるんだ。まるで本のページをめくるみたいに、最初の10行を「飛ばして」11行目から見始める感じ。

シンタックス

SELECT カラム1, カラム2
FROM テーブル
OFFSET スキップする行数;
  • OFFSET — 行をスキップするためのキーワード。
  • スキップする行数 — スキップしたい行の数。

OFFSETのシンプルな使い方例

例えば、studentsテーブルがあって、こんなデータが入ってるとする:

id name age
1 アリサ 22
2 ボブ 24
3 クララ 23
4 ダン 21
5 エバ 25

3番目から学生を表示したいときは、こんなクエリを使う:

SELECT *
FROM students
OFFSET 2;

結果:

id name age
3 クララ 23
4 ダン 21
5 エバ 25

SQLは最初の2行(アリサとボブ)を「スキップ」して、3行目から結果を返してくれる。まるでブックマークみたいに「このページはもう読んだから、次を開こう」って感じだね。

OFFSETLIMITの組み合わせ

OFFSETはよくLIMITと一緒に使うよ。これで行をスキップしつつ、必要な数だけ結果を取得できる。特にページネーション(page=ページ)を作るときに便利で、データを少しずつ表示できるんだ。

例えば、2件ずつ表示して3行目から始めたいときは、こう書く:

SELECT *
FROM students
LIMIT 2 
OFFSET 2;

結果:

id name age
3 クララ 23
4 ダン 21

ロジックはこう:

  1. OFFSET 2で最初の2行(アリサとボブ)をスキップ。
  2. LIMIT 2で残りから2行だけ取る。

ページネーションの作り方

さて、いよいよ本題のページネーションの作り方だよ。例えば、学生リストを表示するWebアプリを作るとして、1ページに2件ずつ表示したいとき、どうする?

基本の考え方:

  • 1ページ目は0行スキップ:OFFSET 0
  • 2ページ目は2行スキップ:OFFSET 2
  • 3ページ目は4行スキップ:OFFSET 4
  • …って感じで続くよ。

例:2ページ目を表示する

1ページ目は1と2(アリサとボブ)、2ページ目は3と4(クララとダン)が表示される。

SELECT *
FROM students
ORDER BY id
LIMIT 2 
OFFSET 2;

結果:

id name age
3 クララ 23
4 ダン 21

例:3ページ目を表示する

3ページ目は5と6(もしあれば)が表示される。

SELECT *
FROM students
ORDER BY id
LIMIT 2 
OFFSET 4;

結果:

id name age
5 エバ 25

OFFSETの計算式

ページネーションのシステムを作るときは、こんな計算式を使うと自動化できるよ:

OFFSET = (ページ番号 - 1) * 1ページあたりの件数

例えば:

  • 1ページ目:(1 - 1) * 2 = 0
  • 2ページ目:(2 - 1) * 2 = 2
  • 3ページ目:(3 - 1) * 2 = 4

パフォーマンスに関する大事な注意

大きなテーブルでOFFSETを使うと、特に後ろのページで効率が悪くなることがある。理由は、PostgreSQLはスキップする行も全部見てから結果を返すから。例えばOFFSET 10000だと、最初の1万行を全部見てから返すことになる。こういう場合は、ページネーションのマーカーとしてユニークIDを使うなど、他の方法も検討しよう。

代替案:カーソルを使ったページネーション

最適化したいときは「カーソル」方式も使える。OFFSETでスキップする代わりに、前のページで取得した最後の行のIDを覚えておいて、それを使って次のクエリを作るんだ:

SELECT *
FROM students
WHERE id > 最後に表示したid
ORDER BY id
LIMIT 2;

この方法だと、大きなテーブルでもかなり速くなることがあるよ。

ページネーションの実用例

ページネーションはほとんどのWebアプリで使われてる。ネットショップ、ブログ、管理画面など。例えば:

  • ネットショップの商品リスト表示;
  • CRMシステムのユーザーリスト表示;
  • ニュースフィードのページごと表示。

また、大量データを分析するときも、少しずつデータを扱うのに便利だよ。

OFFSETでよくあるミス

OFFSETを使うとき、特に勉強中はつまずきやすいポイントがある。よくあるミスを紹介するね:

ソートがない。 ORDER BYを付けないと、OFFSETの結果の行の順番が予測できなくなるよ。

間違ったクエリ:

SELECT * FROM students
OFFSET 5;

正しいクエリ:

SELECT * FROM students
ORDER BY id
OFFSET 5;

OFFSETの値が間違ってる。 大きすぎる値を指定すると、結果が空になる。

パフォーマンスの問題。 さっき話した通り、後ろのページで大きなOFFSETを使うと効率が悪くなる。

フィルターがない。 OFFSETLIMITWHEREなしで使うと、いらないデータまで取ってきてパフォーマンスが落ちることがある。

オペレーターの順番。 SQLのオペレーターの順番は決まってる:まずLIMIT、そのあとOFFSET。省略はOKだけど、順番を変えちゃダメ。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION