すべてのプロダクト
Search
ドキュメントセンター

PolarDB:LIMIT OFFSET pushdown

最終更新日:Mar 29, 2026

ページネーションクエリでは、ページ番号が増加するにつれて処理速度が低下します。これは、標準的な MySQL 実行モデルにおいて、候補となるすべての行が SQL レイヤーに送信され、その後 OFFSET 値に基づいて即座に破棄されるためです。PolarDB for MySQL では、LIMIT OFFSET の評価をストレージエンジン層にプッシュダウンすることでこのオーバーヘッドを削減し、不要な行を送信前にフィルタリングします。

仕組み

標準的な MySQL では、LIMIT 句は SQL レイヤーで評価されます。ストレージエンジンは候補となるすべての行を SQL レイヤーに送信し、SQL レイヤーが OFFSET 値に基づいて行をスキップして最終的な結果セットを返します。OFFSET 値が大きいページネーションクエリでは、ストレージエンジンが大量の行を送信しますが、それらは即座に破棄されます。また、ページ番号が増加するにつれて、そのコストは線形に増加します。

LIMIT OFFSET pushdown を有効化すると、PolarDB は行のフィルタリングを SQL レイヤーに到達する前にストレージエンジン層で実行します。これは主に以下の 2 つのシナリオで機能します:

  • SQL レイヤーに WHERE 条件がない場合:述語プッシュダウン機能 detach_range_condition を使用して述語条件が完全にプッシュダウンされた場合、SQL レイヤーで残るフィルタリング処理はありません。この状態では、LIMIT OFFSET を直接プッシュダウンできます。

  • セカンダリインデックスによるアクセスとテーブルルックアップを伴う場合:クエリがセカンダリインデックスを使用し、同時にプライマリテーブルから列も取得する必要がある場合、LIMIT OFFSET pushdown はストレージエンジン層で不要なテーブルルックアップをスキップし、いずれにせよ破棄される行の取得を回避します。

前提条件

この機能を有効化する前に、ご利用の PolarDB for MySQL クラスターが以下のバージョン要件を満たしていることを確認してください:

  • バージョン 8.0、リビジョンバージョン 8.0.1.1.16 以降

  • バージョン 8.0、リビジョンバージョン 8.0.2.2.0 以降

クラスターのバージョンを確認するには、「エンジンバージョンの照会」をご参照ください。

制限事項

LIMIT OFFSET pushdown は、OFFSET 値が 512 より大きい場合にのみ適用されます。OFFSET 値が小さい場合は、スキップする行数が少ないため、プッシュダウンによる調整オーバーヘッドが、標準実行パスに対するメリットを上回ります。

この制限を解除するには、ignore_polar_optimizer_ruleON に設定します。パラメーターの設定方法については、「クラスターおよびノードパラメーターの指定」をご参照ください。

パラメーターレベルデフォルト説明
ignore_polar_optimizer_ruleグローバルおよびセッションOFFOFFSET しきい値制限を制御します。ON に設定すると、しきい値制限が無効化され、任意の OFFSET 値に対してプッシュダウンが可能になります。

LIMIT OFFSET pushdown の有効化/無効化

LIMIT OFFSET pushdown はデフォルトで有効化されています。loose_optimizer_switch パラメーターを使用して、その状態を変更できます。パラメーターの変更手順については、「クラスターおよびノードパラメーターの指定」をご参照ください。

パラメーターレベル変数デフォルト説明
loose_optimizer_switchグローバルおよびセッションlimit_offset_pushdownONLIMIT OFFSET pushdown の有効化/無効化を制御します。
loose_optimizer_switchグローバルおよびセッションdetach_range_conditionON述語プッシュダウンの有効化/無効化を制御します。WHERE 条件が存在する場合、LIMIT OFFSET pushdown はこの機能に依存します。

プッシュダウンが有効であるかの確認

クエリに対して EXPLAIN を実行し、Extra フィールドを確認します。LIMIT OFFSET pushdown が有効な場合、出力に Using limit-offset pushdown が含まれます。この文字列が表示されない場合は、クエリがプッシュダウン条件を満たしていないことを意味します。「プッシュダウンが適用されない場合」で、最も一般的な原因をご確認ください。

以下の例では、TPC-H スキーマを使用しています。

述語条件がない場合(Q1)

WHERE 句のない全表スキャンです。プライマリテーブルに直接アクセスされます。SQL レイヤーで残るフィルタリング処理がないため、LIMIT OFFSET がプッシュダウンされます。

EXPLAIN
SELECT *
FROM lineitem
LIMIT 10000000, 10\G
*************************** 1. 行 ***************************
           id: 1
  select_type: SIMPLE
        table: lineitem
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 59440464
     filtered: 100.00
        Extra: Using limit-offset pushdown

Extra: Using limit-offset pushdown の出力により、行フィルタリングが SQL レイヤーではなくストレージエンジン層で実行されていることが確認できます。

プライマリキーに対する範囲条件(Q2)

WHERE 条件がプライマリキーに基づく場合、述語プッシュダウン機能(detach_range_condition)によって条件が SQL レイヤーから除去され、LIMIT OFFSET のプッシュダウンが可能になります。

EXPLAIN SELECT * FROM lineitem WHERE l_orderkey > 10 AND l_orderkey < 60000000 LIMIT 10000000, 10\G
*************************** 1. 行 ***************************
           id: 1
  select_type: SIMPLE
        table: lineitem
   partitions: NULL
         type: range
possible_keys: PRIMARY,i_l_orderkey,i_l_orderkey_quantity
          key: PRIMARY
      key_len: 4
          ref: NULL
         rows: 29720232
     filtered: 100.00
        Extra: Using limit-offset pushdown

セカンダリインデックスとテーブルルックアップ(Q3)

セカンダリインデックスが使用され、クエリがプライマリテーブルの列も必要とする場合、LIMIT OFFSET pushdown は結果ウィンドウ外にある行に対する不要なプライマリテーブルのルックアップをスキップします。

EXPLAIN SELECT * FROM lineitem WHERE l_partkey > 10 AND l_partkey < 200000 LIMIT 5000000, 10\G
*************************** 1. 行 ***************************
           id: 1
  select_type: SIMPLE
        table: lineitem
   partitions: NULL
         type: range
possible_keys: i_l_partkey,i_l_suppkey_partkey
          key: i_l_suppkey_partkey
      key_len: 5
          ref: NULL
         rows: 11123302
     filtered: 100.00
        Extra: Using limit-offset pushdown

インデックスによる ORDER BY

ORDER BY 句がインデックスによって満たされる場合、述語条件が SQL レイヤーから除去され、LIMIT OFFSET がプッシュダウンされます。

EXPLAIN SELECT * FROM lineitem WHERE l_partkey > 10 AND l_partkey < 200000 ORDER BY l_partkey LIMIT 5000000, 10\G
*************************** 1. 行 ***************************
           id: 1
  select_type: SIMPLE
        table: lineitem
   partitions: NULL
         type: range
possible_keys: i_l_partkey,i_l_suppkey_partkey
          key: i_l_suppkey_partkey
      key_len: 5
          ref: NULL
         rows: 11123302
     filtered: 100.00
        Extra: Using limit-offset pushdown

プッシュダウンが適用されない場合

LIMIT OFFSET pushdown が適用されるには、SQL レイヤーで残るフィルタリング処理がない必要があります。ExtraUsing limit-offset pushdown が表示されない場合は、以下のいずれかの条件が該当していないかご確認ください:

条件プッシュダウンがスキップされる理由
OFFSET 値が 512 以下少数の行をスキップする場合は、プッシュダウン オーバーヘッドがない方が効率的です。オーバーライドするには、ignore_polar_optimizer_ruleON に設定します。
WHERE 条件をストレージエンジンに完全にプッシュダウンできないSQL レイヤーで残るフィルタリング処理があると、LIMIT OFFSET のプッシュダウンは阻止されます。これは、クエリでファイルソートや非インデックス化された ORDER BY が使用されている場合に発生します。

パフォーマンス向上効果

以下の図は、スケールファクター 10 の TPC-H データセットを用いた測定結果を示しており、Q1、Q2、Q3 の各クエリについて、LIMIT OFFSET pushdown を有効化した場合と無効化した場合のクエリ実行時間の改善効果を比較しています。

Performance improvements