無料PHPプログラム

MySQL 5.1 リファレンスマニュアル :: 6 最適化 :: 6.2 SELECTステートメントおよびその他のクエリの最適化 :: 6.2.9 LEFT JOINとRIGHT JOIN最適化
« 6.2.8 DISTINCT最適化

6.2.10 入れ子結合最適化 »
Section Navigation      [Toggle]
  • 6.2 SELECTステートメントおよびその他のクエリの最適化
  • 6.2.1 EXPLAINを使用して、クエリを最適化する
  • 6.2.2 クエリパフォーマンスの推定
  • 6.2.3 SELECTクエリの速度
  • 6.2.4 WHERE 節最適化
  • 6.2.5 Range 最適化
  • 6.2.6 インデックス結合最適化
  • 6.2.7 IS NULL最適化
  • 6.2.8 DISTINCT最適化
  • 6.2.9 LEFT JOINとRIGHT JOIN最適化
  • 6.2.10 入れ子結合最適化
  • 6.2.11 外側Join 単純化
  • 6.2.12 ORDER BY最適化
  • 6.2.13 GROUP BY最適化
  • 6.2.14 LIMITの最適化
  • 6.2.15 テーブルスキャンを避ける方法
  • 6.2.16 INSERTステートメントの速度
  • 6.2.17 UPDATEステートメントの速度
  • 6.2.18 DELETEステートメントの速度
  • 6.2.19 その他の最適化のヒント

6.2.9. LEFT JOINとRIGHT JOIN最適化

MySQL の AB join_conditionは以下のように実装されます。

  • テーブルBはテーブル Aと Aが依存するすべてのテーブルに依存するように設定される。

  • テーブル Aは、LEFT JOIN条件で使用されるすべてのテーブル(Bを除く)に依存するように設定される。

  • LEFT JOIN条件は、テーブル Bからのレコードの取り出し方法の判定に使用される。(言い換えると、WHERE節の条件はいずれも使用されない)。

  • あるテーブルが全てのテーブルの後に読み取られる場合を除き、通常の最適化全てが行われる。依存関係が循環している場合は、MySQL からエラーが出力される。

  • 標準の WHERE最適化すべてが実行される。

  • AにWHERE節の条件にマッチするレコードがあり、Bに ON条件にマッチするレコードがない場合、Bのカラムの値が NULLに設定されたレコードが生成される。

  • テーブルのいずれかに存在しないレコードを検索する際に LEFT JOINを使用した場合: col_name IS NULLのWHERE節内で、NOT NULLと定義した col_name を column_name IS NULL で評価した場合、 MySQL は LEFT JOIN条件に一致するレコードを 1 つ検索すると、その後はレコードの検索(特定のキー組み合わせの)を停止する。

RIGHT JOINの実装は LEFT JOINと類似しています。

結合オプティマイザがテーブルの結合順序を計算します。テーブル読み取り順序は LEFT JOINと STRAIGHT_JOINによって強制されるため、チェック対象のテーブル順列が減少し、結合オプティマイザ(テーブルの結合順序を計算する)の動作の速度がさらに上がります。 LEFT JOINが dの前に読み取るように強制するため、MySQL では bの完全スキャンが実行されることに注目してください。

SELECT *
  FROM a JOIN b LEFT JOIN c ON (c.key=a.key) 
  LEFT JOIN d ON (d.key=a.key)
  WHERE b.key=d.key;

この場合の修正は逆さに行われ、aとbがFROM節でリストされています。

SELECT *
  FROM b JOIN a LEFT JOIN c ON (c.key=a.key) 
  LEFT JOIN d ON (d.key=a.key)
  WHERE b.key=d.key;

LEFT JOINにとって、生成された NULL行で WHERE条件が常にfalseである場合、LEFT JOINは通常の結合に変更されます。 たとえば、t2.column1カラムが NULLであるとすると、以下のクエリの WHERE節は falseになります:

SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;

よって、通常の結合に変換しても問題ありません。

SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;

これでクエリが改善できる場合、MySQL がテーブル t1を読み取る前にテーブル t2を使用できるようになるためスピードが向上します。テーブルの順序を指定して強制する場合は STRAIGHT_JOINを使用します。

Copyright c 1997, 2010, Oracle and/or its affiliates. All rights reserved. Legal Notices
Top / Previous / Next / Up / Table of Contents
© 2010, Oracle Corporation and/or its affiliates

無料CGI PHPスクリプト | 新着情報スクリプト | 営業日カレンダー | PHPマニュアル | MySQLマニュアル | PEARマニュアル

Copyright (c) 2010 jmcodex.com All rights reserved.