実行時にパフォーマンスの違いを示したコンテンツをクエリする2つの異なる方法がありました。最初の方法は
EXPLAIN select SOME_COLUMNS
from
( select *
from A
where CONDITION
) p
inner join
( select *
from B
)st
on p.id = st.id;
そして、このクエリの出力は次を返しました。
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "Extra"
1 PRIMARY derived3 ALL NULL NULL NULL NULL 25607 " "
1 PRIMARY derived2 ALL NULL NULL NULL NULL 21037 Using where; Using join buffer
3 DERIVED A ALL NULL NULL NULL NULL 23202 " "
2 DERIVED B ref IDX_A_TYPE_ID IDX_A_ID 98 " " 12411 Using where
他の方法は
EXPALIN SELECT SOME_COLUMNS
FROM A p, B s
WHERE p.id = s.id
AND p.CONDITION;
この出力は次のようになります。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE p ref PRIMARY,IDX_A_TYPE_ID IDX_A_TYPE_ID 98 const 12411 Using where
1 SIMPLE s ref PRIMARY PRIMARY 4 local_db.p.entity_id 1
クエリ実行の各ステップでフェッチされる2行と行数の間にクエリ実行プランにこのような違いがあるのはなぜですか?説明してください。
実行パフォーマンスは次の理由で異なります。
最初のケースでは、内部テーブルが作成されると、WHERE
条件で列名を指定しない限り、インデックスなしで作成されます。したがって、テーブルtemp_A
およびtemp_B
WHERE
条件の変数をインデックスキーとして使用して作成されます。ただし、WHERE条件でindex-idを指定すると、インデックス値を使用してその一時テーブルを作成するのに時間がかかります。
2番目のケースでは、インデックス値に基づいてすでに作成されている2つのテーブルの結合には、最初のクエリで発生した前処理は必要ありません。
違いがあります:
最初のクエリでは、次のことを行います。
A
からのデータをCONDITION
でフィルタリングして一時テーブルを作成しますB
からのデータを使用して一時テーブルを作成しますtemp_A
の各行について、temp_B
をトラバースします。この場合、temp_A
フルスキャンを使用し、temp_B
インデックスによるアクセス2番目のクエリ
A
に該当するCONDITION
の各行について、テーブルB
と結合します。2番目のクエリでわかるように、データをテーブルに「プリロード」し、スキャンはさまざまな方法で機能します。