技術系(Tips)
PR

MySQLのLIMIT句、カンマ区切りはもう古い?SQL標準「FETCH NEXT」へ移行すべき理由とDB各社の対応状況

saratogax
記事内に商品プロモーションを含む場合があります

MySQL を使っているエンジニアにとって、レコードの取得件数を制限する LIMIT 句はお馴染みの存在です。しかし、LIMIT 20, 10 のようなカンマ区切りの書き方が「MySQL 特有の書き方(方言)」であることをご存知でしょうか。

近年、クラウドネイティブな環境(AWS Aurora など)やモダンなユニットテスト環境(H2 Database 2.x)への移行が進む中で、この「書き方」の選択が将来のメンテナンス性に大きな影響を与えるようになっています。

本記事では、MySQL の LIMIT 句の変遷から、各 DB エンジンの対応状況、そしてなぜ今「標準 SQL」への完全移行がベストプラクティスなのかを解説します。

LIMIT 句の 3 つの書き方とその違い

現在、主要な RDBMS では以下の 3 つの形式で件数制限が行われています。

① MySQL 特有(カンマ区切り)

SELECT * FROM orders LIMIT 20, 10;
  • 特徴: 左が OFFSET(飛ばす数)、右が LIMIT(取る数)。
  • リスク: どちらがどっちか直感的に分かりにくく、書き間違いが発生しやすい。

② デファクトスタンダード(LIMIT OFFSET)

SELECT * FROM orders LIMIT 10 OFFSET 20;
  • 特徴: PostgreSQL や SQLite でも採用されており、可読性が高い。
  • リスク: 多くの DB で動くが、実はこれでも「標準規格」ではない。

③ 標準 SQL 準拠(OFFSET FETCH NEXT)

SELECT * FROM orders 
OFFSET 20 ROWS 
FETCH NEXT 10 ROWS ONLY;
  • 特徴: SQL:2008 で定義された公式な書き方。
  • メリット: 最も寿命が長く、Oracle や SQL Server との互換性も高い。

FETCH NEXT 10 ROWS ONLYFETCH NEXT 1 ROW ONLY。英語としては単数・複数を使い分けたくなりますが、SQL標準およびMySQLでは、どちらを使っても構いません。コードの統一感を出すために、常に ROWS に固定してしまう現場も多いです。

標準構文である OFFSET ... FETCH が MySQL でサポートされたのはバージョン 8.0.22 からです。AWS Aurora の場合、MySQL 8.0 互換である Aurora 3.x 系であれば問題なく動作しますが、5.7 互換の 2.x 系以前では動作しないため注意が必要です。

主要データベースエンジンの対応状況比較

将来的に DB を乗り換える、あるいはマルチ DB 環境で開発する場合、LIMIT の有無は大きな壁になります。

データベースエンジンLIMIT 句OFFSET / FETCH NEXT備考
MySQL (Aurora 3.x)○ (推奨)8.0.22以降で標準構文に対応
PostgreSQL古くから両方の構文に対応
SQL Server×LIMIT非対応(TOP句またはOFFSET-FETCH)
Oracle (12c以降)×12cから標準SQLのFETCH句を導入
H2 Database (2.x)2.x系より標準SQL準拠を強力に推進
※表は横スクロールできます。標準SQLである「FETCH NEXT」が最も汎用性が高い。

特に、SQL Server や Oracle では LIMIT 句が使えません。 将来の選択肢を広げるなら、標準 SQL への準拠が唯一の正解となります。

なぜ「一気に標準 SQL(FETCH NEXT)」へ移行すべきか?

もし、既存のアプリケーション(MyBatis など)で大量のクエリを修正する必要があるなら、中途半端に「カンマを外す」だけの対応はもったいないと言えます。

理由1:二度手間(技術的負債)の解消

「カンマなし LIMIT」に直しても、将来的に「完全な標準化」が求められたら再度全修正が必要です。修正コスト(テスト・デプロイ工数)を一回で済ませるなら、最初からゴール(標準規格)を目指すべきです。

理由2:Aurora 3.x と H2 2.x の強力なサポート

AWS Aurora (MySQL 8.0互換) や、ユニットテストで多用される H2 Database の最新版(2.xなど)は、既にこの標準構文をフルサポートしています。開発・テスト・本番の全環境で「共通言語」が使える条件は整っています。

理由3:MyBatis 等での型安全・ケアレスミス防止

MyBatis の XML 等で LIMIT #{offset}, #{limit} と書くよりも、OFFSET #{offset} ROWS FETCH NEXT #{limit} ROWS ONLY と書くほうが、パラメータの役割が明示的になります。これにより、引数の順番を逆にするようなバグを構造的に防げます。

まとめ:将来を見据えた「堅実な」選択

クラウド環境が当たり前になった今、特定の DB エンジンの方言に依存し続けるリスクは無視できません。

  • 新規開発: 無条件で OFFSET ... FETCH NEXT ... を採用する。
  • 既存改修: 修正のついでに「ボーイスカウト・ルール」で標準化を進める。

「郷に入れば郷に従え」も一理ありますが、エンジニアとして「どこへ行っても通用するコード」を書くことは、システムにとっても、あなた自身のキャリアにとっても、最も堅実な投資になるはずです。

ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました