OFFSETとは?SQL初心者向けに基本から使い方までわかりやすく解説
OFFSET(オフセット)とは、SQLの検索結果から指定した件数を読み飛ばし、その次のデータから取得するための機能です。
例えば、検索結果の先頭20件を飛ばして21件目から表示したい場合にOFFSETを使用します。Webシステムのページ送りや、大量データを分割して確認するときによく使われます。
- OFFSETとは?
- OFFSETはどんな場面で使われるのか
- OFFSETが重要な理由
- OFFSETの基本イメージ
- MySQL・PostgreSQLでの基本構文
- SQL Serverでの基本構文
- Oracle Databaseでの基本構文
- OFFSETとLIMITの違い
- ページネーションでの計算方法
- ORDER BYと組み合わせる理由
- 同じ日時のデータがある場合の注意点
- 実際のIT現場での利用例
- 業務でよくあるトラブル
- 原因を切り分ける順番
- GUIでの確認方法
- CUIでの確認方法
- ログの確認方法
- イベントビューアーを確認する場面
- ショートカットキー
- 初心者がやりがちなミス
- 筆者の経験談
- 大きなOFFSETが遅い理由
- 性能を改善する方法
- OFFSETを使わないページング方法
- 上司へ報告するポイント
- エスカレーションするタイミング
- 新人が覚えておくべきポイント
- 関連するIT用語
- よくある質問(FAQ)
- まとめ
OFFSETとは?
OFFSETには「位置をずらす」という意味があります。
SQLでは、検索結果の先頭から何件読み飛ばすかを指定します。
OFFSETだけで取得件数を制限するのではなく、MySQLやPostgreSQLではLIMIT、SQL ServerではFETCH NEXTなどと組み合わせることが一般的です。
OFFSETはどんな場面で使われるのか
- 社員一覧を20件ずつ表示する
- 検索結果の2ページ目以降を表示する
- 大量のログを100件単位で確認する
- APIからデータを分割して取得する
- バッチ処理で対象データを一定件数ずつ読み込む
特に、一覧画面のページネーションで使われることが多い機能です。
OFFSETが重要な理由
大量のデータを一度に表示すると、画面が見にくくなり、データベースやネットワークにも負荷がかかります。
OFFSETを利用すると、表示する開始位置をずらせるため、検索結果をページ単位に分割できます。
ただし、OFFSETの値が大きくなると処理が遅くなる場合があります。実務では、便利な機能である一方、性能面にも注意が必要です。
OFFSETの基本イメージ
社員テーブルに次のデータが登録されているとします。
| 社員ID | 氏名 |
|---|---|
| 1001 | 山田 |
| 1002 | 佐藤 |
| 1003 | 鈴木 |
| 1004 | 田中 |
| 1005 | 高橋 |
OFFSET 2を指定すると、先頭の2件を読み飛ばします。
| 社員ID | 氏名 |
|---|---|
| 1003 | 鈴木 |
| 1004 | 田中 |
| 1005 | 高橋 |
OFFSET 2は、2件目から取得するという意味ではありません。先頭2件を飛ばし、3件目から取得するという意味です。
MySQL・PostgreSQLでの基本構文
SELECT * FROM 社員 ORDER BY 社員ID LIMIT 10 OFFSET 20;
このSQLでは、社員ID順に並べた結果の先頭20件を読み飛ばし、21件目から10件取得します。
MySQLでは、次のような書き方もできます。
SELECT * FROM 社員 ORDER BY 社員ID LIMIT 20, 10;
最初の20が読み飛ばす件数、次の10が取得件数です。ただし、意味を理解しやすくするため、LIMITとOFFSETを分けて書く現場もあります。
SQL Serverでの基本構文
SQL Serverでは、ORDER BYとOFFSET、FETCH NEXTを組み合わせます。
SELECT * FROM 社員 ORDER BY 社員ID OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
先頭20件を読み飛ばし、その次の10件を取得します。
SQL ServerでOFFSETを使用する場合は、ORDER BYが必要です。
Oracle Databaseでの基本構文
Oracle Databaseでは、次のように記述できます。
SELECT * FROM 社員 ORDER BY 社員ID OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
比較的新しいOracle Databaseでは、SQL Serverと似た構文を使用できます。
OFFSETとLIMITの違い
| 項目 | OFFSET | LIMIT |
|---|---|---|
| 役割 | 読み飛ばす件数を指定する | 取得する件数を指定する |
| 例 | 先頭20件を飛ばす | 10件だけ取得する |
| 主な用途 | 取得開始位置の指定 | 取得件数の制限 |
LIMITは「何件取るか」、OFFSETは「何件飛ばすか」と覚えると分かりやすくなります。
ページネーションでの計算方法
1ページあたり20件表示する場合、OFFSETは次の式で求められます。
OFFSET = 1ページあたりの件数 × (表示ページ番号 − 1)
| ページ | LIMIT | OFFSET |
|---|---|---|
| 1ページ目 | 20 | 0 |
| 2ページ目 | 20 | 20 |
| 3ページ目 | 20 | 40 |
| 4ページ目 | 20 | 60 |
3ページ目を表示する場合は、先頭40件を飛ばし、41件目から20件取得します。
ORDER BYと組み合わせる理由
OFFSETを使用するときは、基本的にORDER BYも指定します。
SELECT * FROM 社員 ORDER BY 社員ID LIMIT 10 OFFSET 20;
ORDER BYがない場合、データの表示順は保証されません。そのため、同じOFFSETを指定しても、実行するタイミングによって取得結果が変わる可能性があります。
ページ送りでは、社員IDや登録日時など、値が安定している列で並び替えることが重要です。
同じ日時のデータがある場合の注意点
登録日時だけで並び替えると、同じ日時を持つデータの順番が毎回変わる可能性があります。
その場合は、主キーなどを2番目の並び替え条件として追加します。
SELECT * FROM 社員 ORDER BY 登録日時 DESC, 社員ID DESC LIMIT 10 OFFSET 20;
このように指定すると、同じ登録日時のデータも社員IDで順番を確定できます。
実際のIT現場での利用例
| 業務 | 利用例 |
|---|---|
| 社員管理 | 社員一覧を50件ずつ表示する |
| ログ調査 | 101件目から100件分のログを確認する |
| 販売管理 | 商品一覧の3ページ目を表示する |
| API連携 | データを一定件数ずつ取得する |
| 運用保守 | 大量レコードを分割して確認する |
業務でよくあるトラブル
1ページ目のデータが表示されない
1ページ目なのにOFFSETへページサイズを指定している可能性があります。
1ページ目のOFFSETは0です。
ページ間で同じデータが表示される
ORDER BYの条件が不十分で、表示順が安定していない可能性があります。
主キーなど、一意に近い列を並び替え条件へ追加します。
一部のデータが飛ばされる
ページ移動中にデータの追加や削除が行われると、OFFSETの位置がずれることがあります。
後ろのページほど表示が遅い
OFFSETの値が大きくなるほど、データベースが読み飛ばす件数も増えます。
数百万件あるテーブルで大きなOFFSETを使うと、性能が低下しやすくなります。
原因を切り分ける順番
- ORDER BYが指定されているか確認する
- 並び替え条件が一意に近いか確認する
- LIMITやFETCH NEXTの件数を確認する
- OFFSETの計算式を確認する
- 元データの追加や削除が発生していないか確認する
- 実行計画やインデックスを確認する
現場では、いきなりSQLを書き換えるのではなく、まずページ番号、1ページの件数、実際に設定されたOFFSETを確認すると効率的です。
GUIでの確認方法
次のデータベース管理ツールでSQLを実行できます。
- MySQL Workbench
- pgAdmin
- DBeaver
- SQL Server Management Studio(SSMS)
- Oracle SQL Developer
まずOFFSETを0で実行し、次に10、20と増やして結果が正しく移動するか確認します。
CUIでの確認方法
各データベースのコマンドラインツールでも確認できます。
- MySQLのmysqlコマンド
- PostgreSQLのpsqlコマンド
- SQL Serverのsqlcmd
- Oracle DatabaseのSQL*Plus
SQLを実行した後は、取得件数だけでなく、最初と最後のIDも確認するとページの重複や欠落を見つけやすくなります。
ログの確認方法
OFFSETの指定ミスは、通常Windowsのイベントビューアーには記録されません。
確認対象は、アプリケーションログ、SQL実行ログ、データベースのスロークエリログなどです。
- 実際に発行されたSQL
- LIMITやOFFSETへ設定された値
- SQLの実行時間
- 取得件数
- タイムアウトの有無
イベントビューアーを確認する場面
OFFSETの結果がずれるだけなら、イベントビューアーの確認は通常不要です。
データベース接続エラー、アプリケーション停止、サービス異常が発生している場合は、Windowsのイベントビューアーで「Windowsログ」の「アプリケーション」や「システム」を確認します。
ショートカットキー
| キー | 用途 |
|---|---|
| F5 | SQLを実行するツールがある |
| Ctrl + A | SQL全文を選択する |
| Ctrl + F | SQLや結果内を検索する |
| Ctrl + C | 選択した内容をコピーする |
| Ctrl + Z | 直前の編集を元に戻す |
ショートカットの動作は、利用するデータベース管理ツールによって異なる場合があります。
初心者がやりがちなミス
- OFFSETを取得開始番号だと勘違いする
- 1ページ目にOFFSET 1を指定する
- ORDER BYを付けずにページ送りする
- LIMITとOFFSETの順番を混同する
- SQL ServerでもLIMITが使えると思い込む
- 大きなOFFSETによる性能低下を考慮しない
筆者の経験談
業務システムの一覧画面で、「2ページ目に同じデータが表示される」という問い合わせを受けたことがあります。
SQLを確認すると、登録日時だけでORDER BYしており、同じ時刻に登録されたデータの順番が安定していませんでした。
登録日時に加えて主キーも並び替え条件へ追加したところ、重複表示は解消しました。この経験から、OFFSETを使う場合は件数だけでなく、並び順が確定しているかを必ず確認しています。
大きなOFFSETが遅い理由
OFFSET 100000を指定した場合、データベースは先頭から10万件分を確認したうえで、そのデータを読み飛ばすことがあります。
取得するのが10件だけでも、読み飛ばす処理に時間がかかるため、後ろのページほど遅くなりやすい傾向があります。
性能を改善する方法
- ORDER BYに使用する列へ適切なインデックスを設定する
- 不要な列をSELECTしない
- WHERE句で対象範囲を絞る
- 大きなOFFSETを避ける
- 主キーを基準に次のデータを取得する
インデックスの追加は更新処理にも影響します。本番環境へ追加する場合は、データベース管理者や上司へ確認してください。
OFFSETを使わないページング方法
大量データでは、最後に取得したIDを条件にして次のデータを取得する方法があります。
SELECT * FROM 社員 WHERE 社員ID > 1000 ORDER BY 社員ID LIMIT 20;
この方法は、キーセットページネーションやカーソル方式と呼ばれます。
大きなOFFSETを読み飛ばす必要がないため、高速になりやすい点がメリットです。ただし、「100ページ目へ直接移動する」といった機能は作りにくくなります。
上司へ報告するポイント
- 発生している画面や機能
- 対象ユーザーと影響範囲
- ページ番号と1ページの表示件数
- 実際に設定されたOFFSET
- ORDER BYの指定内容
- 重複や欠落が発生したデータ
- SQLの実行時間
- 再現条件と調査結果
エスカレーションするタイミング
- 本番画面でデータの重複や欠落が発生している
- ページ表示に長時間かかる
- タイムアウトが発生している
- インデックスの追加や変更が必要
- SQLの修正が他機能へ影響する可能性がある
- 利用者が必要なデータを確認できない
新人が覚えておくべきポイント
- OFFSETは先頭から読み飛ばす件数を指定する
- OFFSET 0は1件も読み飛ばさない
- LIMITは取得件数、OFFSETは開始位置を調整する機能
- ORDER BYと組み合わせて使う
- 安定した並び順には主キーも指定する
- 大きなOFFSETは遅くなる場合がある
関連するIT用語
- SQL(Structured Query Language)
- SELECT
- LIMIT
- ORDER BY
- FETCH NEXT
- WHERE
- インデックス(Index)
- ページネーション(Pagination)
- 主キー(Primary Key)
- 実行計画
よくある質問(FAQ)
OFFSET 10は10件目から取得するという意味ですか?
いいえ。先頭10件を読み飛ばし、11件目から取得するという意味です。
1ページ目のOFFSETはいくつですか?
0です。先頭から表示するため、読み飛ばすデータはありません。
OFFSETだけで取得件数を指定できますか?
OFFSETは読み飛ばす件数を指定する機能です。取得件数を制限する場合は、LIMITやFETCH NEXTなどを組み合わせます。
OFFSETを使うとデータは削除されますか?
削除されません。検索結果の一部を読み飛ばして表示するだけで、テーブル内のデータは変更されません。
OFFSETを使うと検索が遅くなりますか?
小さい値では問題にならないことが多いですが、数万件や数十万件を読み飛ばす場合は遅くなる可能性があります。
SQL ServerでもOFFSETを使えますか?
使用できます。ただし、ORDER BYが必要で、取得件数を指定する場合はFETCH NEXTを組み合わせます。
まとめ
OFFSETは、SQLの検索結果から指定した件数を読み飛ばし、その次のデータから取得するための機能です。
一覧画面のページ送りや大量データの分割取得でよく利用されます。LIMITやFETCH NEXTと組み合わせることで、表示開始位置と取得件数を指定できます。
実務では「OFFSETは何件飛ばすか」「LIMITは何件取得するか」と覚えましょう。また、ORDER BYで安定した並び順を指定し、大きなOFFSETによる性能低下にも注意することが重要です。
