ページネーションクエリでは、ページ番号が増加するにつれて処理速度が低下します。これは、標準的な 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_rule を ON に設定します。パラメーターの設定方法については、「クラスターおよびノードパラメーターの指定」をご参照ください。
| パラメーター | レベル | デフォルト | 説明 |
|---|---|---|---|
ignore_polar_optimizer_rule | グローバルおよびセッション | OFF | OFFSET しきい値制限を制御します。ON に設定すると、しきい値制限が無効化され、任意の OFFSET 値に対してプッシュダウンが可能になります。 |
LIMIT OFFSET pushdown の有効化/無効化
LIMIT OFFSET pushdown はデフォルトで有効化されています。loose_optimizer_switch パラメーターを使用して、その状態を変更できます。パラメーターの変更手順については、「クラスターおよびノードパラメーターの指定」をご参照ください。
| パラメーター | レベル | 変数 | デフォルト | 説明 |
|---|---|---|---|---|
loose_optimizer_switch | グローバルおよびセッション | limit_offset_pushdown | ON | LIMIT OFFSET pushdown の有効化/無効化を制御します。 |
loose_optimizer_switch | グローバルおよびセッション | detach_range_condition | ON | 述語プッシュダウンの有効化/無効化を制御します。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 pushdownExtra: 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 レイヤーで残るフィルタリング処理がない必要があります。Extra に Using limit-offset pushdown が表示されない場合は、以下のいずれかの条件が該当していないかご確認ください:
| 条件 | プッシュダウンがスキップされる理由 |
|---|---|
| OFFSET 値が 512 以下 | 少数の行をスキップする場合は、プッシュダウン オーバーヘッドがない方が効率的です。オーバーライドするには、ignore_polar_optimizer_rule を ON に設定します。 |
| WHERE 条件をストレージエンジンに完全にプッシュダウンできない | SQL レイヤーで残るフィルタリング処理があると、LIMIT OFFSET のプッシュダウンは阻止されます。これは、クエリでファイルソートや非インデックス化された ORDER BY が使用されている場合に発生します。 |
パフォーマンス向上効果
以下の図は、スケールファクター 10 の TPC-H データセットを用いた測定結果を示しており、Q1、Q2、Q3 の各クエリについて、LIMIT OFFSET pushdown を有効化した場合と無効化した場合のクエリ実行時間の改善効果を比較しています。
