web-dev-qa-db-ja.com

mysqlは2つの方法で参加します-どのように機能しますか? -パフォーマンスに違いがあります

実行時にパフォーマンスの違いを示したコンテンツをクエリする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行と行数の間にクエリ実行プランにこのような違いがあるのはなぜですか?説明してください。

5
nizha

実行パフォーマンスは次の理由で異なります。

  • 最初のケースでは、内部テーブルが作成されると、WHERE条件で列名を指定しない限り、インデックスなしで作成されます。したがって、テーブルtemp_Aおよびtemp_BWHERE条件の変数をインデックスキーとして使用して作成されます。ただし、WHERE条件でindex-idを指定すると、インデックス値を使用してその一時テーブルを作成するのに時間がかかります。

  • 2番目のケースでは、インデックス値に基づいてすでに作成されている2つのテーブルの結合には、最初のクエリで発生した前処理は必要ありません。

1
nizhashree

違いがあります:

  1. 最初のクエリでは、次のことを行います。

    • AからのデータをCONDITIONでフィルタリングして一時テーブルを作成します
    • Bからのデータを使用して一時テーブルを作成します
    • temp_Aの各行について、temp_Bをトラバースします。この場合、temp_Aフルスキャンを使用し、temp_Bインデックスによるアクセス
  2. 2番目のクエリ

    • Aに該当するCONDITIONの各行について、テーブルBと結合します。

2番目のクエリでわかるように、データをテーブルに「プリロード」し、スキャンはさまざまな方法で機能します。

1
ravnur