MySQL inとexistsの最適化について

1904 ワード

最適化の原則:常に小さなテーブル駆動の大きなテーブル
select * from A where id in(select id from B)
   
for select id from B
for select * from A where A.id=B.id
 B         A      , in  exists
     1,      
select * from A where exists(select 1 from B where B.id=A.id)
   
for select * from A
for select * from B where B.id=A.id
 A       B      , exists  in
  :A  B  ID       

Exists
select…from table where exists(subquery)
この構文は、プライマリ・クエリーのデータをサブクエリーに配置して条件検証を行い、検証結果(trueまたはfalse)に基づいてプライマリ・クエリーのデータ結果が保持されるかどうかを決定すると理解できます.
  • exists(subquery)はtrueまたはfalseのみを返すため、サブクエリのselect*はselect 1または他のselect‘x’であってもよく、公式には実際に実行するとselectリストは無視されるため、
  • と区別されない.
  • existsサブクエリの実際の実行プロセスは、効率の問題が懸念される場合、効率の問題があるかどうかを判断するために、理解上の逐条比較ではなく最適化される可能性があります.
  • existsサブクエリは、条件式、他のサブクエリ、またはjoinで置き換えることもよくあります.
    ローの存在を検出するサブクエリを指定します.外見をループして、外見の記録が内表のデータと同じかどうかを見ます.一致すると、結果セットに結果が挿入されます.
    existsキーワードを使用してクエリーを行う場合は、まずサブクエリーの内容ではなく、メインクエリーのテーブルを調べます.
    次に、テーブルの各レコードに基づいて、whereの後の条件が成立しているかどうかを順次判断する文を実行します.
    成立するとtrueが成立しないとfalseが返されます.trueを返すと、ローの結果は保持され、falseを返すと、ローが削除され、最後に得られる結果が返されます.
    in
    指定した値がサブクエリまたはリストの値と一致するかどうかを決定します.inクエリーの場合、まずサブクエリーのテーブルをクエリーし、内部テーブルと外観をデカルト積にし、条件に従ってフィルタします.だから内表が比較的小さい時、inの速度は比較的に速いです
    inとexistsの違い
    AテーブルのデータがBテーブルのデータと同じ大きい場合、inとexistsの効率はあまり悪くなく、任意に1つ使用することができる.inとexistsの違い:サブクエリで得られた結果セットのレコードが少ない場合、メインクエリのテーブルが大きく、インデックスがある場合はinを使用します.逆に、外側層のメインクエリのレコードが少ない場合、サブクエリのテーブルが大きく、インデックスがある場合はexistsを使用します.実はinとexistsを区別するのは主に駆動順序の変化(これが性能の変化の鍵である)をもたらしたので、existsであれば外層表を駆動表として先にアクセスされ、INであれば先にサブクエリを実行するので、駆動表の迅速な戻りを目標とし、インデックスと結果セットの関係を考慮し、またINではNULLを処理しない.
    inは外見と内表をhash接続し,existsは外表に対してloopループを行い,loopループのたびに内表をクエリーする.従来existsはinより効率が高いと考えられていた説は正確ではない.
    not inとnot exists
    クエリー文がnot inを使用している場合、内外のテーブルはすべて全テーブルスキャンされ、インデックスは使用されません.not extstsのサブクエリは、テーブルのインデックスにも使用できます.だからその時計が大きくてもnot existsを使うのはnot inより速いです.