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

PolarDB:LEFT JOIN 除去

最終更新日:Mar 28, 2026

高度に正規化されたスキーマやビューに基づくクエリレイヤーでは、多くの LEFT JOIN 句を含む SQL が生成されることが多く、その大部分は論理的に冗長です。つまり、結合されるテーブルが結果セットに一切寄与していません。LEFT JOIN 除去は、オプティマイザーのレベルでこうした冗長な結合を削除する機能であり、データベースは実際に必要なテーブルのみを読み込みます。複雑な分析クエリにおいては、SQL を一切変更せずに実行時間を 10 倍以上短縮できます。

仕組み

クエリ内の各 LEFT JOIN について、PolarDB for MySQL は以下の 2 つの条件を検証します。

  1. 左側テーブルの各行に対して、右テーブルの行は結合条件を満たすものが 1 行のみ存在すること。

  2. 右テーブルの列が、SELECT リストまたはクエリ内の他の任意の場所で参照されていないこと。

両条件を満たす場合、PolarDB は実行計画から当該結合を削除します。オプティマイザーはクエリ内のすべての LEFT JOIN に対してこの検証を適用するため、複数の冗長な結合を同時に除去できます。

前提条件

開始する前に、以下の条件を満たしていることを確認してください。

  • PolarDB for MySQL 8.0 クラスター(リビジョンバージョン 8.0.1.1.32 以降、または 8.0.2.2.10 以降)

制限事項

LEFT JOIN 除去は、以下の **両方** の条件が満たされた場合にのみ適用されます。

  • 左側テーブルの各行に対して、右テーブルの行は結合条件を満たすものが 1 行のみ存在すること。

  • 右テーブルの列が、LEFT JOIN 句自体以外の SQL ステートメント内のいかなる場所でも参照されていないこと。

LEFT JOIN 除去の有効化

loose_join_elimination_mode パラメーターを設定することで、本機能の有効化タイミングを制御できます。

パラメーターレベル説明
loose_join_elimination_modeグローバルLEFT JOIN 除去を制御します。デフォルト値: REPLICA_ON。有効な値: ON(全ノードで有効)、REPLICA_ON(読み取り専用ノードのみで有効)、OFF(無効)。

パラメーターの変更については、「クラスターおよびノードのパラメーターの指定」をご参照ください。

説明

デフォルト値 REPLICA_ON では、読み取り専用ノードでのみ本機能が有効になります。プライマリノードを含む全ノードで有効にするには、パラメーターを ON に設定してください。

EXPLAIN による検証

EXPLAIN を使用して、LEFT JOIN 除去がクエリに適用されているかを確認できます。

最適化前

以下のクエリでは、table1(エイリアス:sc)、table2(エイリアス:ca)、table3(エイリアス:co)が結合されています。各 table1 の行は、table2 および table3 の行とそれぞれ 1 対 1 でマッチし、table2 および table3 の列は SELECT リストに一切出現しません。したがって、両方の除去条件を満たしています。

EXPLAIN
SELECT count(*)
FROM `table1` `sc`
  LEFT JOIN `table2` `ca` ON `sc`.`car_id` = `ca`.`id`
  LEFT JOIN `table3` `co` ON `sc`.`company_id` = `co`.`id`;

出力:

+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref                   | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+
|  1 | SIMPLE      | sc    | NULL       | ALL    | NULL          | NULL    | NULL    | NULL                  |    2 |   100.00 | NULL        |
|  1 | SIMPLE      | ca    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | je_test.sc.car_id     |    1 |   100.00 | Using index |
|  1 | SIMPLE      | co    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | je_test.sc.company_id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+

実行計画には 3 つのテーブルがすべて表示されます。実行時間:7.5 秒。

最適化後

LEFT JOIN 除去が有効化されている場合、オプティマイザーは table2 および table3 への結合が冗長であると検出し、クエリを書き換えて table1 のみをスキャンするようにします。

EXPLAIN
SELECT count(*)
FROM `table1` `sc`

出力:

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | sc    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+

実行計画には table1 のみが残ります。実行時間:0.1 秒 — 元のクエリと比較して 75 倍高速です。

関連トピック