SQL と MySQL のステートメント実行順序の分析

SQL と MySQL のステートメント実行順序の分析

今日、問題が発生しました: MySQL の insert into、update、delete ステートメントで as エイリアスを使用できますか?まだ調査中ですが、SQL および MySQL ステートメントの実行順序に関する情報を調べているときに、いくつか役立つ知識が見つかったので、皆さんと共有したいと思います。
sql と mysql の実行順序は、内部メカニズムが同じであることを示しています。最大の違いはエイリアスの参照にあります。

1. SQL実行順序

(1)から

(2)オン

(3)参加する

(4)ここで

(5) group by (selectでエイリアスを使い始めると、後続のステートメントでも使えるようになります)

(6)平均、合計....

(7)持つ

(8)選択

(9)明確な

(10)順序

このシーケンスから、すべてのクエリ ステートメントがから開始して実行されていることが簡単にわかります。実行プロセス中に、各ステップで次のステップの仮想テーブルが生成され、この仮想テーブルが次の実行ステップの入力として機能します。

ステップ 1: まず、from 句の最初の 2 つのテーブルに対して直積を実行し、仮想テーブル vt1 を生成します (ベース テーブルとして比較的小さなテーブルを選択します)。

ステップ 2: 次のステップは、on フィルターを適用することです。on の論理式は vt1 の各行に適用され、on 論理式に一致する行がフィルタリングされ、仮想テーブル vt2 が生成されます。

ステップ 3: 外部結合の場合、このステップでは外部行が追加されます。左外部結合では、2 番目のステップで左側のテーブルからフィルターされた行が追加されます。右外部結合の場合、2 番目のステップで右側のテーブルからフィルターされた行が追加されます。これにより、仮想テーブル vt3 が生成されます。

ステップ 4: from 句のテーブルの数が 2 を超える場合、vt3 は 3 番目のテーブルに接続され、直積を計算して仮想テーブルを生成します。このプロセスは、ステップ 1 ~ 3 を繰り返して、最終的に新しい仮想テーブル vt3 を取得するものです。

ステップ 5: where フィルターを適用し、前のステップで作成された仮想テーブルに where フィルターを参照して、仮想テーブル vt4 を生成します。ここで言及する必要がある重要な詳細があります。外部結合句を含むクエリの場合、論理式は on フィルターで指定するべきか、それとも where フィルターで指定するべきかという紛らわしい疑問があります。 on と where の最大の違いは、on で論理式を適用すると、削除された行を 3 番目のステップの外部結合で再度追加できるのに対し、where の削除は最終的なものであることです。簡単な例を挙げると、生徒テーブル (クラス、名前) とスコア テーブル (名前、スコア) があります。クラス x のすべての生徒のスコアを返す必要がありますが、このクラスの数人の生徒は試験を受けられなかったため、スコア テーブルにはレコードがありません。期待される結果を得るためには、on 句で学生と成績テーブルの関係を指定する必要があります (student.name = grade.name)。次に、2 番目のステップを実行すると、試験を受けなかった学生のレコードは論理式 on によってフィルタリングされるため、vt2 に表示されないことがわかります。ただし、クラス x のすべての学生を返す必要があるため、左外部結合を使用して、左テーブル (学生) の試験を受けなかった学生を取得できます。on で student.class='x' が適用されている場合、左外部結合はクラス x のすべての学生レコードを取得します (修正してくれたネットユーザー Kang Qinmou__Kang Qinmiao に感謝します)。そのため、フィルタリングが最終的なものであるため、where フィルターでのみ student.class='x' を適用できます。

ステップ 6: group by 句は、一意の値をグループに結合して仮想テーブル vt5 を取得します。 group by が適用されると、後続のすべてのステップでは、vt5 列または集計関数 (count、sum、avg など) のみを取得できます。その理由は、最終的な結果セットにはグループごとに 1 行しか含まれていないためです。このことを心に留めておいてください。

ステップ 7: キューブまたはロールアップ オプションを適用して、vt5 のスーパーグループを生成し、vt6 を生成します。

ステップ 8: having フィルターを適用して vt7 を生成します。所有フィルターは、グループ化されたデータに適用される最初の、そして唯一のフィルターです。

ステップ 9: 選択句を処理します。 vt7 の選択に表示される列を除外します。 vt8 を生成します。

ステップ 10: distinctive 句を適用して、vt8 から同一の行を削除し、vt9 を生成します。実際、group by 句が適用されると、distinct は冗長になります。その理由は、グループ化すると、列内の一意の値がグループ化され、グループごとに 1 行のレコードのみが返されるため、すべてのレコードが異なることになるからです。

ステップ 11: order by 句を適用します。 vt9 を order_by_condition でソートし、仮想テーブルの代わりにカーソルを返します。 SQL は集合論に基づいています。集合では行が事前にソートされません。集合は単にメンバーの論理的な集合であり、メンバーの順序は関係ありません。テーブルを並べ替えるクエリは、特定の物理順序でデータの論理的な構成を含むオブジェクトを返すことができます。このオブジェクトはカーソルと呼ばれます。戻り値はカーソルであるため、order by 句を使用するクエリはテーブル式に適用できません。並べ替えには非常にコストがかかります。並べ替える必要がない限り、order by を指定しないことをお勧めします。最後に、この手順は、選択リストでエイリアスを使用できる最初で唯一の手順です。

ステップ 12: 上位オプションを適用します。そうして初めて、結果が要求者、つまりユーザーに返されます。

2. MySQLの実行順序

SELECT文の定義

完了した SELECT ステートメントには、いくつかのオプションの句が含まれます。 SELECT ステートメントの定義は次のとおりです。

SQL コード

<SELECT 句> [<FROM 句>] [<WHERE 句>] [<GROUP BY 句>] [<HAVING 句>] [<ORDER BY 句>] [<LIMIT 句>]

SELECT 句は必須ですが、WHERE 句や GROUP BY 句などの他の句はオプションです。

SELECT ステートメントでは、句の順序は固定されています。たとえば、GROUP BY 句は WHERE 句の前には配置されません。

SELECT文の実行順序

SELECT ステートメント内の句の実行順序は、SELECT ステートメントに句が入力される順序とは異なるため、実行は SELECT 句から開始されるのではなく、次の順序で実行されます。

開始 -> FROM 句 -> WHERE 句 -> GROUP BY 句 -> HAVING 句 -> ORDER BY 句 -> SELECT 句 -> LIMIT 句 -> 最終結果 各句が実行された後、次の句で使用するための中間結果が生成されます。句が存在しない場合はスキップされます。

比較すると、mysql と sql の実行順序は基本的に同じです。SQL ステートメントの標準的な順序は次のとおりです。

候補者名、最大(合計スコア)をtb_Gradeから最大合計スコアとして選択します  
候補名がnullではない  
最大(合計スコア)が600を超える候補者名でグループ化  
合計スコアの最大値で並べ替え

上記の例では、SQL ステートメントは次の順序で実行されます。

(1)まず、FROM句を実行して、tb_Gradeテーブルのデータソースからデータを組み立てます。

(2)WHERE句を実行して、tb_Gradeテーブル内のNULL以外のすべてのデータをフィルタリングします。

(3) GROUP BY 句を実行して、tb_Grade テーブルを「学生名」列でグループ化します (注: この手順以降、SELECT でのみエイリアスを使用できます。テーブルではなくカーソルが返されるため、SELECT のエイリアスは where 句では使用できませんが、having 句では使用できます。この質問を提起してくれた netizen zyt1369 に感謝します)

(4)max()集計関数を計算し、「合計スコア」に応じて合計スコアの最大値を見つけます。

(5)HAVING句を実行して、合計スコアが600点を超えるコースをフィルタリングします。

(7)ORDER BY句を実行し、最終結果を「最大スコア」で並べ替えます。

私は遭遇した問題を引き続き探求し、もちろん、師匠たちが私に教えてくれることも望んでいます。

要約する

以上が、SQL と MySQL のステートメント実行順序の分析に関するこの記事の内容のすべてです。不足している点がある場合は、メッセージを残してください。編集者がすぐに返信します。

興味のある方は、MySQL のステートメント サブクエリの効率最適化のヒント、MYSQL サブクエリとネストされたクエリの最適化の例の分析、いくつかの重要な MySQL 変数などを参照してください。皆様のお役に立てば幸いです。

以下もご興味があるかもしれません:
  • SQL文の実行順序の図による説明
  • MySQLステートメントの記述と実行順序を理解するだけです
  • SQL ステートメント実行の詳細な説明 (MySQL アーキテクチャの概要 -> クエリ実行プロセス -> SQL 解析順序)
  • SQLクエリの実行順序をゼロから学ぶ
  • Mysql系SQLクエリ文の書き順と実行順を詳しく解説

<<:  Docker を使用して Nginx+Flask+Mongo アプリケーションをデプロイする

>>:  antd+reactプロジェクトをviteに移行するためのソリューションの詳細な説明

推薦する

Linux のソフトリンクとハードリンクの詳細な説明

目次1. ファイルとディレクトリの基本的な保存2. Inコマンドの紹介(1)lnコマンドの基本情報を...

ユーザー名が使用可能かどうかを確認するVueメソッド

この記事では、ユーザー名が使用可能かどうかを確認するためのVueの具体的なコードを例として紹介します...

Linuxでmore、less、catコマンドを使用してファイルの内容を表示します

Linux では、cat、more、less の各コマンドを使用してファイルの内容を表示できます。c...

JavaScript の組み込み Date オブジェクトの詳細な説明

目次日付オブジェクト日付オブジェクトの作成新しい日付()日付を取得する()取得日()月を取得する()...

アイデアコンパイラvueインデントエラー問題シナリオの分析

プロジェクトシナリオ: Vueプロジェクトを実行したらインデントエラーが出ました。ideaコンパイラ...

MySQL 8.0.11 圧縮版のインストールチュートリアル

この記事では、MySQL 8.0.11のインストールチュートリアルを参考までに紹介します。具体的な内...

Vueはソースコード付きのリファレンスライブラリのメソッドを使用します

monaco-editor-vueの公式ソースコードは次のとおりです。インデックス 'mon...

Vueはログイン時に画像認証コードを実装します

この記事では、Vueログイン用画像認証コードの具体的なコードを例として紹介します。具体的な内容は以下...

どのような種類の MYSQL 接続クエリを知っていますか?

序文クエリ情報が複数のテーブルから取得される場合、クエリのためにこれらのテーブルを結合する必要があり...

Dockerコンテナイメージからコードを復元する手順

コードが失われ、コンテナ内で実行されているイメージから必要なコードを回復する必要がある場合があります...

CentOS7 (YUM) での MySQL 5.7 のインストールと設定のチュートリアル

インストール環境: CentOS7 64ビット、MySQL5.7 1. YUMソースを設定するMyS...

Nginx を使用してフロントエンドのクロスドメイン問題を解決する方法

序文Vue アプリケーションなどの静的ページを開発する場合、クロスドメインになる可能性のあるインター...

win10 での mysql5.7.21 の詳細なインストール手順

この記事では、MySQL 5.7.21のインストールとインストール中に発生した問題を参考までに紹介し...

Vue3 スロットの使用状況の概要

目次1. Vスロットの紹介2. 匿名スロット3. 名前付きスロット4. スコープ付きスロット5. 動...

マウスがカード上に移動したときにフローティング効果を実現する CSS の使用例

原理ホバーしたときに要素に影を設定します: box-shadow で、通常とは異なるスタイルにします...