[MySQLスタディノート(12)]クエリオプティマイザのルールベースの最適化とサブクエリの最適化

この記事は公式アカウント[DevelopingPigeon]から公開されています!フォローへようこそ!


古いルール-姉妹都市都市:

1。クエリオプティマイザのルールベースの最適化

(I.概要

       クエリオプティマイザは、対応するルールに従ってクエリステートメントを最適化し、効率的に実行できる形式に変換します。このプロセスは、クエリの書き換えと呼ばれます。

(2)条件付き簡略化

1.不要な括弧を削除します

       式の余分な括弧を削除します。

2.コンスタントパス

       列と定数が等しい値で一致している場合、AND演算子を使用してこの式を列に関連する他の式に接続すると、列を定数に変換できます。

といった:

a = 5 AND b > a

a = 5 AND b > 5

3.既知の条件を削除します

       明らかにTRUEまたはFALSEである式の場合、オプティマイザーはそれらを削除します。

4.式の計算

       クエリが実行される前に、式に定数のみが含まれている場合、その値が最初に計算されます。

5.一定のテーブル検出

       レコードが1つ以下のテーブル、または主キーと一意のセカンダリインデックス列が一致するテーブルの場合、これら2種類のテーブルはクエリにほとんど時間がかからないため、定数テーブルと呼ばれます。クエリオプティマイザは、クエリステートメントを分析するときに、最初に定数テーブルの検出を実行して定数テーブルがあるかどうかを確認し、次にクエリ内のテーブルに関連するすべての条件を定数に置き換えてから、他のテーブルのクエリコストを分析します。


(3)外部接続の排除

       なぜ外部結合を排除するのですか?内部結合は、オプティマイザを介してテーブルのさまざまな結合順序のコストを評価し、クエリを実行するために最もコストの低い結合順序を選択できるためです。

       理由がわかったら、それを取り除く方法を見てみましょう。WHERE句の検索条件で、ドリブンテーブルの列がNULLでないことを指定している限り、WHERE句の条件を満たさないすべてのレコードは接続に参加しません(この条件はnull値の拒否と呼ばれます)。 )の場合、これらの外部接続は次のようになります。ドライブテーブルのON句の条件に一致しないドライブテーブルレコードは、最終結果セットに表示されません。このとき、外部結合と内部結合は同じであり、目的は同じです。外側の結合を排除することが達成されます。


二。サブクエリの最適化

(1)サブクエリ

1。概要

       サブクエリは、FROM句、WHERE句、ON句などにあるかどうかに関係なく、クエリステートメントにクエリをネストすることです。サブクエリはネストでき、外部クエリは外部クエリと呼ばれます。FROM句に配置されたサブクエリは、テーブルのクエリと同等であるため、派生テーブルと呼ばれます。

2.返された結果セットに従った分類

(1)スカラー量子クエリ

       単一の値のサブクエリのみを返します。

(2)行サブクエリ

       複数の列を含む必要があるレコードを返すサブクエリ。

(3)列子クエリ

       列のデータをクエリするには、複数のレコードが含まれている必要があります。

(4)テーブルサブクエリ

       サブクエリの結果には、複数のレコードと複数の列が含まれます。


3.外部クエリとの関係に従って分類

(1)無関係なサブクエリ

       サブクエリは独立して実行されて結果を生成し、外部クエリの値に依存しません。

(2)関連するサブクエリ

       サブクエリの実行は、外部クエリの値によって異なります。

4.ブール式でのサブクエリの使用

(1)比較演算子で使用する

(2)IN / NOT IN
操作数 [NOT] IN (子查询)

       クエリ結果セットで構成されるセットに存在するかどうか。

(3)任意/一部
操作数 比较操作符 ANY/SOME(子查询)

       サブクエリの結果セットに値がある限り、指定されたオペランドが比較演算子を介して値と比較されると、結果はTRUEになり、式全体がTRUEになります。

(4)すべて
操作数 比较操作符 ALL(子查询)

       指定されたオペランドが比較演算子を介してサブクエリの結果セット内のすべての値と比較された場合にのみ、結果はTRUEになり、式全体がTRUEになります。

(5)存在する
[NOT] EXISTS (子查询)

       サブクエリの結果セットにレコードがあるかどうかを判断するだけでよく、レコードが何であるかは関係ありません。

5.サブクエリに関する注意事項

       (1)サブクエリは括弧を使用する必要があります

       (2)SELECT句のサブクエリはスカラーサブクエリである必要があります

       (3)ステートメント内のテーブルのレコードを追加、削除、または変更し、同時にテーブルをサブクエリすることは許可されていません。


(2)MySQLでサブクエリがどのように実行されるか

1.標準サブクエリ、行サブクエリ

(1)無関係なサブクエリ

       サブクエリを個別に実行し、サブクエリで取得した結果を外部クエリのパラメータとして使用してから、外部クエリ、つまり複数の単一テーブルクエリを実行します。

(2)関連するサブクエリ

       最初に外部クエリからレコードを取得し、次にこのレコードからサブクエリに含まれる値を見つけてサブクエリを実行し、最後にサブクエリのクエリ結果に従って外部クエリの条件が確立されているかどうかを確認します。が確立されると、外部クエリレイヤークエリのレコードが結果セットに追加されます。それ以外の場合は破棄されます。

2.INサブクエリの最適化

(1)具体化表

       無関係なINサブクエリの場合、サブクエリの結果セットが大きすぎると、パフォーマンスの問題が発生する可能性があります。内部ストレージが十分でない場合、インデックスを効果的に使用できません。したがって、結果セットは外部クエリのパラメータとして直接使用されませんが、結果セットは一時テーブルに書き込まれ、書き込まれたレコードはスペースを節約するために重複排除されます。一時テーブルは、メモリに基づくMEMORYストレージエンジンを使用し、テーブルのハッシュインデックスも確立されます。結果セットが特に大きい場合、一時テーブルはディスクベースのストレージエンジンに変換され、結果セットが保存されます。インデックスもB +ツリーインデックスになります。一時テーブルを作成するこのプロセスはマテリアライゼーションと呼ばれ、一時テーブルはマテリアライズテーブルと呼ばれます。

       新しいテーブルが生成されたので、マテリアライズテーブルに対して他のテーブルとの内部結合操作を実行でき、コストを計算することで最もコストの低い実行方法を見つけることができます。

(2)半接続

       マテリアライズテーブルには、一時テーブルの作成コストがかかります。MySQLは、サブクエリを直接結合に変換する半結合を提案しています。s1テーブルとs2テーブルの半結合は、s1テーブル内のレコードについて、s2テーブル内に一致するレコードがあるかどうかのみを考慮し、一致するレコードの数は関係しないことを意味します。最終結果はs1テーブルのレコードはコレクションに保持されます。

       5つの半結合実行戦略があり、半結合はMySQL内の最適化戦略であり、ユーザーに公開されているインターフェースではありません。


3. [NOT] EXISTSサブクエリ

       関係のないサブクエリの場合は、最初にサブクエリを実行し、結果がTRUEまたはFALSEの場合は、元のクエリステートメントを書き直します。相関サブクエリの場合は、前の標準サブクエリの相関サブクエリと同じ方法でのみクエリを実行でき、EXISTSサブクエリをキャプチャしてインデックスを高速化できます。

4.派生テーブルの最適化

       FROM句に配置されたサブクエリは派生テーブルであり、MySQLは2つの実行戦略を提供します。1つは、派生テーブルをマテリアライズして一時テーブルに書き込み、マテリアライズされたテーブルを通常のテーブルとして処理してクエリに参加することです。MySQLには遅延マテリアライズ戦略もあり、派生テーブルが実際に存在する場合にのみマテリアライズされます。クエリで使用されます。派生テーブル。もう1つは、派生テーブルを外部クエリとマージし、派生テーブルのない形式で記述し、派生テーブルをFROM句に抽出して、検索条件をWHERE句にマージすることです。

       MySQLは最初に派生テーブルを外部クエリとマージしようとします。それが機能しない場合は、派生テーブルをマテリアライズしてクエリを実行します。

おすすめ

転載: blog.csdn.net/Mrwxxxx/article/details/113839762