この最適化は、インデックスが設定されていないカラムと定数との直接比較の効率性を向上します。 このような場合、条件が評価のためにストレージエンジンに「プッシュダウン」されます。 この最適化は、NDB
ストレージエンジンでのみ使用できます。
NDB Cluster の場合、この最適化により、クラスタデータノードとクエリーを発行した MySQL サーバーの間で一致しない行をネットワーク経由で送信する必要がなくなり、条件プッシュダウンが可能だが使用されない場合に 5 から 10 倍の係数で使用されるクエリーを高速化できます。
「NDB Cluster」テーブルが次のように定義されているとします:
CREATE TABLE t1 (
a INT,
b INT,
KEY(a)
) ENGINE=NDB;
エンジン条件プッシュダウンは、インデックス付けされていないカラムと定数の比較を含む、次に示すようなクエリーで使用できます:
SELECT a, b FROM t1 WHERE b = 10;
エンジン条件プッシュダウンの使用は、EXPLAIN
の出力で確認できます:
mysql> EXPLAIN SELECT a,b FROM t1 WHERE b = 10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10
Extra: Using where with pushed condition
ただし、エンジン条件プッシュダウンは、次のクエリーでは使用できません:
SELECT a,b FROM t1 WHERE a = 10;
カラム a
にインデックスが存在するため、エンジン条件プッシュダウンはここでは適用できません。 (インデックスアクセスメソッドの方が効率的であるため、コンディションプッシュダウンよりも優先して選択されます。)
エンジン条件プッシュダウンは、インデックス付けされたカラムが >
または <
演算子を使用して定数と比較される場合にも使用できます:
mysql> EXPLAIN SELECT a, b FROM t1 WHERE a < 2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: range
possible_keys: a
key: a
key_len: 5
ref: NULL
rows: 2
Extra: Using where with pushed condition
エンジン条件プッシュダウンでサポートされているその他の比較には、次のものがあります:
-
column
[NOT] LIKEpattern
pattern
は、照合するパターンを含む文字列リテラルである必要があります。構文については、セクション12.8.1「文字列比較関数および演算子」を参照してください。 column
IS [NOT] NULL-
column
IN (value_list
)value_list
の各項目は定数のリテラル値である必要があります。 -
column
BETWEENconstant1
ANDconstant2
constant1
とconstant2
はそれぞれ、定数のリテラル値である必要があります。
前のリストのすべての場合で、条件をカラムと定数との 1 つ以上の直接比較の形式に変換できます。
エンジンコンディションプッシュダウンはデフォルトで有効です。 サーバーの起動時に無効にするには、optimizer_switch
システム変数の engine_condition_pushdown
フラグを off
に設定します。 たとえば、my.cnf
ファイルで、次の行を使用します。
[mysqld]
optimizer_switch=engine_condition_pushdown=off
実行時に、次のように条件プッシュダウンを無効にします:
SET optimizer_switch='engine_condition_pushdown=off';
制限. エンジンコンディションプッシュダウンには次の制限があります。
エンジン条件プッシュダウンは、
NDB
ストレージエンジンでのみサポートされます。NDB 8.0.18 より前では、カラムは定数または定数値にのみ評価される式と比較できました。 NDB 8.0.18 以降では、カラムがまったく同じタイプであるかぎり、カラムを相互に比較できます (それらが該当する場合は、同じ符号性、長さ、文字セット、精度、およびスケールを含む)。
比較に使用されるカラムは、
BLOB
型またはTEXT
型のいずれかであってはいけません。 この除外は、JSON
、BIT
およびENUM
カラムにも拡張されます。カラムと比較される文字列値は、カラムと同じ照合順序を使用する必要があります。
結合は直接サポートされていません。複数のテーブルを含む条件は、可能な場合に個別にプッシュされます。 拡張
EXPLAIN
出力を使用して、実際にプッシュダウンされる条件を決定します。 セクション8.8.3「拡張 EXPLAIN 出力形式」を参照してください。
以前は、エンジン条件プッシュダウンは、条件のプッシュ先と同じテーブルのカラム値を参照する用語に制限されていました。 NDB 8.0.16 以降では、クエリープラン内の以前のテーブルのカラム値をプッシュされた条件から参照することもできます。 これにより、結合処理中に SQL ノードで処理する必要がある行数が削減されます。 フィルタリングは、単一の mysqld プロセスではなく LDM スレッドで並列に実行することもできます。 これにより、クエリーのパフォーマンスが大幅に向上する可能性があります。
NDB 8.0.20 以降では、スキャンを使用する外部結合は、同じ結合入れ子で使用されるテーブル、またはそれが依存する結合 nmests 内のテーブルにプッシュ不可能な条件がない場合にプッシュできます。 これは、使用される最適化戦略が firstMatch
である場合にには、準結合でも当てはまります (セクション8.2.2.1「準結合変換による IN および EXISTS サブクエリー述語の最適化」 を参照)。
次の 2 つの状況では、結合アルゴリズムを前のテーブルの参照カラムと組み合せることはできません:
参照された以前のテーブルのいずれかが結合バッファ内にある場合。 この場合、スキャンフィルタ処理されたテーブルから取得された各行は、バッファ内のすべての行と照合されます。 つまり、スキャンフィルタの生成時にカラム値をフェッチできる単一の特定の行はありません。
プッシュされた結合の子操作からカラムが作成された場合。 これは、スキャンフィルタの生成時に、結合の祖先操作から参照される行がまだ取得されていないためです。