ちょっと質問!ネットショップのサイトで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行目から結果を返してくれる。まるでブックマークみたいに「このページはもう読んだから、次を開こう」って感じだね。
OFFSETとLIMITの組み合わせ
OFFSETはよくLIMITと一緒に使うよ。これで行をスキップしつつ、必要な数だけ結果を取得できる。特にページネーション(page=ページ)を作るときに便利で、データを少しずつ表示できるんだ。
例えば、2件ずつ表示して3行目から始めたいときは、こう書く:
SELECT *
FROM students
LIMIT 2
OFFSET 2;
結果:
| id | name | age |
|---|---|---|
| 3 | クララ | 23 |
| 4 | ダン | 21 |
ロジックはこう:
OFFSET 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を使うと効率が悪くなる。
フィルターがない。 OFFSETやLIMITをWHEREなしで使うと、いらないデータまで取ってきてパフォーマンスが落ちることがある。
オペレーターの順番。 SQLのオペレーターの順番は決まってる:まずLIMIT、そのあとOFFSET。省略はOKだけど、順番を変えちゃダメ。
GO TO FULL VERSION