MySQL リミットとオフセットの例

⚡ スマートサマリー

その MySQL LIMITキーワードはクエリが返す行数を制限し、OFFSET値は結果の開始行を決定します。これらを組み合わせることで、結果セットのサイズを小さく保ち、ページの読み込み速度を向上させ、レコードごとのページネーションを実現します。

  • 🔢 コア行動: LIMIT N は最大で N 行を返します。N 行より少ない行数を持つテーブルは、エラーなくすべての行を返します。
  • 0️⃣ ゼロケース: LIMIT 0 は行を返さないため、列のメタデータを検査する手軽な方法となります。
  • 📍 オフセット構文: LIMIT 1, 2 は 1 行をスキップして 2 を返すため、オフセットが最初に書き込まれ、行数が次に書き込まれます。
  • 📄 ページネーションの計算式: OFFSETは、ページサイズにページ番号を掛けた値から1を引いた値に等しく、これにより結果セットが番号付きページに変換されます。
  • ↕️ 順序依存性: ORDER BY なし、 MySQL 実行ごとに異なる行が返される可能性があるため、LIMIT は明示的なソートを行った場合にのみ決定論的になります。
  • ⚙️ 声明の裏付け: LIMIT句はUPDATEとDELETEによって影響を受ける行数を制限し、大規模なテーブルを無制限の書き込みから保護します。
  • 🐢 パフォーマンスに関する注意点: 大きなオフセットは MySQL スキップされた行はすべて読み込んで破棄するため、深いページが大きくなる速度が遅くなります。

MySQL LIMITとOFFSET

LIMITキーワードとは何ですか MySQL?

その LIMIT キーワードは、クエリ結果で返される行数を制限します。SELECT、UPDATE、DELETE ステートメントで使用できるため、クエリが読み取る行数と書き込みが影響を与える行数を制限できます。

LIMITキーワードの構文は以下のとおりです。

SELECT {fieldname(s) | *} FROM tableName(s) [WHERE condition] LIMIT N;

Pr_media

  • 「SELECT {フィールド名 | *} FROM tableName(s)”SELECTステートメント クエリで返したいフィールドが含まれています。
  • 「[WHERE条件]」 オプションですが、指定すると結果セットのフィルタを指定します。 WHERE句 は LIMIT より前に適用されるため、フィルタリングが最初に行われ、残ったものに上限が適用されます。
  • 「Nの制限」 がキーワードであり、 N は0から始まる任意の数値です。制限値に0を指定すると、レコードは返されません。例えば5を指定すると、5件のレコードが返されます。テーブル内のレコード数がNより少ない場合は、すべてのレコードが返され、エラーは発生しません。

構文は短いが、例を挙げる前に、その存在理由を述べておく価値がある。

なぜLIMITキーワードを使うべきなのか?

私たちが開発していると仮定しますping myflixdb上で動作するアプリケーションについて、システム設計者から、読み込み速度の低下を防ぐため、1ページに表示されるレコード数を20件に制限するよう求められています。このような要件を満たすシステムをどのように実装すればよいでしょうか?

LIMITキーワードはまさにこの状況に対応します。アプリケーションにすべてのメンバー行を取り込んでそのほとんどを破棄する代わりに、クエリは1ページあたり20件のレコードを返し、データベースが処理を行います。これによって3つの利点が得られます。

  • より速い応答: ディスクから読み込まれるデータ量が少なくなり、ネットワークを通過するデータ量も少なくなる。
  • メモリ使用量を削減する: アプリケーションにはテーブル全体ではなく、1ページ分の行が格納されます。
  • セーファー氏は次のように書いています。 更新または DELETE このステートメントは、エラーが影響を与える行数を制限します。

MySQL LIMITクエリの例

以下の例は、myflixdbデータベースのmembersテーブルに対して実行されます。最初の例では、2行のみが返され、それ以上の情報は返されません。

SELECT * FROM members LIMIT 2;
会員番号 フルネーム 性別 生年月日 登録日 実在住所 郵便番号 連絡先番号 メール クレジットカード番号
1 ジャネット・ジョーンズ 女性 21-07-1980 NULL 第一街区画 No 4 専用バッグ 0759 253 542 janetjones@yagoo.cm NULL
2 ジャネット・スミス・ジョーンズ 女性 23-06-1980 NULL メルローズ 123 NULL NULL jj@fstreet.com NULL

上記の結果が示すように、返還されたメンバーはわずか2名でした。

データベースから10人のメンバーのリストを取得する

Myflixデータベースから登録済みの上位10名のリストを取得したいとします。以下のスクリプトは、それらのリストを要求するものです。

SELECT * FROM members LIMIT 10;

スクリプトを実行すると、以下の結果が得られます。

会員番号 フルネーム 性別 生年月日 登録日 実在住所 郵便番号 連絡先番号 メール クレジットカード番号
1 ジャネット・ジョーンズ 女性 21-07-1980 NULL 第一街区画 No 4 専用バッグ 0759 253 542 janetjones@yagoo.cm NULL
2 ジャネット・スミス・ジョーンズ 女性 23-06-1980 NULL メルローズ 123 NULL NULL jj@fstreet.com NULL
3 ロバート・フィル 男性 12-07-1989 NULL サード ストリート 3 NULL 12345 rm@tstreet.com NULL
4 グロリア・ウィリアムズ 女性 14-02-1984 NULL セカンドストリート2 NULL NULL NULL NULL
5 レナード・ホフスタッター 男性 NULL NULL ウッドクレスト NULL 845738767 NULL NULL
6 シェルドン・クーパー 男性 NULL NULL ウッドクレスト NULL 976736763 NULL NULL
7 ラジェッシュ・クースラパリ 男性 NULL NULL ウッドクレスト NULL 938867763 NULL NULL
8 レスリー・ウィンクル 男性 14-02-1984 NULL ウッドクレスト NULL 987636553 NULL NULL
9 ハワード・ウォロウィッツ 男性 24-08-1981 NULL サウスパーク PO Box 4563 987786553 lwolowitz[at]email.me NULL

LIMIT句のNがテーブルのレコード数より大きいため、返されたメンバーは9人だけです。明示的に9行を要求すると、同じ結果セットが得られます。

SELECT * FROM members LIMIT 9;

💡ヒント: LIMIT は、サーバーが生成する順序に関係なく行を選択します。 ORDER BY 行の同一性が重要な場合は常にこの条項を適用してください。そうでない場合、「最初の10人」が同じ9人を2回意味するとは限らないためです。

行数を制限するのがこの機能の前半部分です。ウィンドウの開始位置を選択するのが後半部分です。

LIMITクエリでOFFSET値を使用する

その OFFSET value は、LIMIT キーワードと組み合わせて使用​​されることが最も多いです。これは、サーバーがデータの取得を開始する行を指定するもので、その行より前の行はスキップされます。

テーブルの中央から始まる限られた数のメンバーのみを表示したいとします。以下のスクリプトは2行目から開始し、結果を2件のレコードに限定します。

SELECT * FROM `members` LIMIT 1, 2;

実行すると MySQL ワークベンチ myflixdbに対して以下の結果を得ました。

会員番号 フルネーム 性別 生年月日 登録日 実在住所 郵便番号 連絡先番号 メール クレジットカード番号
2 ジャネット・スミス・ジョーンズ 女性 23-06-1980 NULL メルローズ 123 NULL NULL jj@fstreet.com NULL
3 ロバート・フィル 男性 12-07-1989 NULL サード ストリート 3 NULL 12345 rm@tstreet.com NULL

ここで注意 オフセット= 1したがって、2行目が最初に返される行であり、 制限 = 2そのため、2件のレコードしか返ってきません。

2つの引数を持つ形式では、オフセットが最初に記述され、行数が次に記述されるため、誤って逆になってしまう可能性があります。 MySQL また、曖昧さを解消する明示的な形式も受け入れており、新しいコードではそちらを優先すべきである。

SELECT * FROM `members` LIMIT 2 OFFSET 1;

どちらのステートメントも同じ2行を返します。オフセットが理解できれば、すべてのリスト画面が依存するページネーションパターンがそこから直接導き出されます。

LIMITとOFFSETを使用してクエリ結果をページ分割する方法

ページネーションは、大量の検索結果を番号付きのページに分割する機能で、LIMITとOFFSETを組み合わせることで実現されます。ページリクエストは、1つの画面に表示されるレコード数であるページサイズと、ユーザーが要求するページ番号という2つの値によって制御されます。

オフセットは、単一の計算式を用いてそれらから導き出されます。

-- OFFSET = page_size * (page_number - 1)
SELECT membership_number, full_names
FROM members
ORDER BY membership_number ASC
LIMIT 20 OFFSET 0;   -- page 1

2ページ目は同じ制限を維持し、オフセットを1ページ分前方に移動させます。

SELECT membership_number, full_names
FROM members
ORDER BY membership_number ASC
LIMIT 20 OFFSET 20;  -- page 2

ページ分けされたリストを正確かつ迅速に作成するための3つのルール。

  1. 常に並べ替え: ORDER BY句のないページネーションクエリでは、サーバーが呼び出し間で行の順序を変更できるため、同じレコードが2つの異なるページに表示され、別のレコードが完全に非表示になる可能性があります。
  2. 一意の列でソートする: ソート列で同順位が発生した場合、同順位の行の順序は確定しません。主キーでソートするか、主キーをタイブレーカーとして追加することで、この問題は解消されます。
  3. 詳細なページをご覧ください: オフセット100000力 MySQL 10万行を読み込んで破棄し、次の20行を返す。応答時間はページ番号に比例して長くなる。

非常に深いページネーションの場合、キーセットページネーションはオフセットを完全に回避します。スキップする行数を数える代わりに、クエリは前のページの最後のキーを記憶し、そのキー以降の行を要求します。

SELECT membership_number, full_names
FROM members
WHERE membership_number > 20      -- last id from the previous page
ORDER BY membership_number ASC
LIMIT 20;

この形式は、インデックスが前の行をたどるのではなく、開始キーに直接ジャンプするため、どの深さでも高速です。ただし、ページは順番にたどる必要があるため、ジャンプはping 500ページに直接アクセスすることはできなくなりました。

制限 MySQL vs TOP と FETCH FIRST

LIMIT句はすべてのSQL方言に含まれているわけではないため、クエリがデータベースエンジン間を移動する必要がある場合には、この点が重要になります。 MySQL, PostgreSQL, SQLite LIMIT キーワードを共有します。SQL Server は TOP を使用し、 Oracle 標準のFETCH FIRST句を使用します。以下の表は、これら3つの構文を比較したものです。

エンジン 例: 行をスキップします
制限…オフセット MySQL, PostgreSQL, SQLite SELECT * FROM members LIMIT 20 OFFSET 40; はい、オフセット付きです
TOP SQLサーバー メンバーの中から上位20件を選択します。 いいえ、OFFSET … FETCH が必要です
最初にフェッチ OracleDb2、標準SQL SELECT * FROM members FETCH FIRST 20 ROWS ONLY; はい、OFFSET … ROWS を使用すれば可能です。

いずれの場合も動作は同じです。行数を制限し、必要に応じて最初に一定数の行をスキップします。違いはスペルだけです。複数のエンジンで実行する必要のあるクエリでは、行数制限句をコードベース全体に散在させるのではなく、分離しておくべきです。

よくあるご質問

はい。どちらも、例えば行数のような単純なカウントを受け入れます。 DELETE FROM members LIMIT 10。ここでは2引数オフセット形式は許可されていないため、影響を受ける行数のみを制限できます。

オフセットはゼロから始まるため、OFFSET 0は最初の行から、OFFSET 1は2番目の行から始まります。行数自体は単なる数値であり、通常の数値として読み取られます。

同じ WHERE 句で LIMIT を指定せずに、別の SELECT COUNT(*) を実行してください。COUNT はアプリケーションに存在するページ数を示し、LIMIT クエリは現在のページの行を返します。

多くの場合、そうです。クライアント内のAIアシスタントは、 MySQL ワークベンチ OFFSETクエリを、最後に検出されたキーに基づいてWHERE句に書き換えます。書き換えを実行する前に、ソート対象の列が一意であり、インデックスが設定されていることを確認してください。

生成されたステートメントでは通常 ORDER BY が省略されるため、明示的なソートがない場合、 MySQL 行の順序は任意となるため、同じLIMIT句でも実行ごとに異なるサンプルが生成される場合があります。ソート処理はご自身で追加してください。