MySQL 8.0 リファレンスマニュアル


8.2.1.15 IS NULL の最適化

MySQL は、col_name = constant_value に対して使用できる同じ最適化を col_name IS NULL に対しても実行できます。 たとえば、MySQL は、インデックスと範囲を使用して、IS NULL を含む NULL を検索できます。

例:

SELECT * FROM tbl_name WHERE key_col IS NULL;

SELECT * FROM tbl_name WHERE key_col <=> NULL;

SELECT * FROM tbl_name
  WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL;

WHERE 句に、NOT NULL として宣言されているカラムの col_name IS NULL 条件が含まれている場合、その式は最適化により除去されます。 この最適化は、カラムが NULL を生成する可能性がある場合 (たとえば、LEFT JOIN の右側のテーブルから生成される場合) には発生しません。

MySQL は、解決済みのサブクエリーで一般的な形式である col_name = expr OR col_name IS NULL の組み合わせを最適化することもできます。 この最適化が使用された場合、EXPLAINref_or_null と示されます。

この最適化は、任意のキーパートに対して 1 つの IS NULL を処理できます。

テーブル t2 のカラム a および b にインデックスがあるとして、最適化されるクエリーのいくつかの例:

SELECT * FROM t1 WHERE t1.a=expr OR t1.a IS NULL;

SELECT * FROM t1, t2 WHERE t1.a=t2.a OR t2.a IS NULL;

SELECT * FROM t1, t2
  WHERE (t1.a=t2.a OR t2.a IS NULL) AND t2.b=t1.b;

SELECT * FROM t1, t2
  WHERE t1.a=t2.a AND (t2.b=t1.b OR t2.b IS NULL);

SELECT * FROM t1, t2
  WHERE (t1.a=t2.a AND t2.a IS NULL AND ...)
  OR (t1.a=t2.a AND t2.a IS NULL AND ...);

ref_or_null はまずリファレンスキーの読み取りを行い、次に NULL キー値のある行の個別の検索を実行します。

最適化では、単一の IS NULL レベルのみを処理できます。 次のクエリーでは、MySQL は式 (t1.a=t2.a AND t2.a IS NULL) に対してのみキールックアップを使用し、b に対してはキーパートを使用できません。

SELECT * FROM t1, t2
  WHERE (t1.a=t2.a AND t2.a IS NULL)
  OR (t1.b=t2.b AND t2.b IS NULL);

関連キーワード:  テーブル, インデックス, InnoDB, WHERE, ステートメント, col, クエリー, FROM, OR, 結合