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に移行するためのソリューションの詳細な説明

推薦する

Reactプロジェクトの新規作成からデプロイまでの実装例

新しいプロジェクトを始めるこの記事では主に、新規プロジェクトを0から1まで取り組むプロセスを記録し、...

NginxにおけるRewriteのリダイレクト設定と実践の詳しい解説

1: アドレス書き換えとア​​ドレス転送の意味を理解する。アドレス書き換えとア​​ドレス転送は異なる...

Centos 7 mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar の簡単な分析

Baiduクラウドディスク:リンク: https://pan.baidu.com/s/1hv5rUW...

docker cp ファイルをコピーしてコンテナに入る

実行中のコンテナに入る # コンテナに入り、新しいターミナルを開きます# docker exec -...

JavaScript フロー制御 (ループ)

目次1. forループ2. 二重の for ループ3. whileループ4. dowhileループ5...

MySQL EXPLAIN出力列の詳細な説明

1. はじめにEXPLAIN ステートメントは、MySQL がステートメントを実行する方法に関する情...

サイバーパンクスタイルのボタンを実現するためのHTML+CSS

まず効果を見てみましょう: 序文:このアイデアは、Bilibili のアップロード者 Steven ...

MacでのMySQL5.7.22のインストール手順

1. インストールパッケージを使用してMySQLをインストールします(オンラインダウンロードは遅すぎ...

uniapp は日付と時刻の選択機能を実装します

この記事の例では、日付と時刻の選択を実装するための uniapp の具体的なコードを参考までに共有し...

JavaScript の parseInt() の魔法についての簡単な説明

原因このブログを書いた理由は、今日Leetcodeの日課問題をやっていたからです。文字列を整数(at...

ウェブページのコアコンテンツ(画像とテキスト)の視覚的表現の紹介

情報の最適化と改良は常にデザインの最初のステップです。 「これは百度アライアンスユーザーエクスペリエ...

MYSQLの文字セット設定方法(端末の文字セット)の詳しい説明

序文ターミナルを使用してデータベースまたはテーブルを作成するたびに、文字セットが latin1 であ...

CSS3は赤い封筒を振る効果を実現します

赤い封筒の揺れ効果を実現するには要件があります。これまでやったことがないので、記録しておきます。ヘヘ...

Linux で MySQL スケジュールタスクを実装する方法

前提: ストアド プロシージャは、毎日午後 10 時から午前 5 時まで 10 分ごとに実行されます...

MySQLにおける正規表現の一般的な使用法

MySQL における Regexp の一般的な使用法特定の文字列を含むあいまい一致# コンテンツフィ...