この記事の内容は、MySQL で SQL ステートメントを実行する方法についてです。一定の参考値があるので、困っている友人は参考にしていただければ幸いです。
この記事では、MySQL 内で SQL クエリがどのように流れるか、SQL ステートメントの更新がどのように完了するかなど、MySQL における次の SQL ステートメントの実行プロセスを分析します。
分析する前に、MySQL のインフラストラクチャを見てみましょう。MySQL がどのコンポーネントで構成され、これらのコンポーネントの機能が何であるかを知ることは、これらの問題を理解し、解決するのに役立ちます。
#A MySQL インフラストラクチャ分析
1.1 MySQL の基本アーキテクチャの概要次の図は、MySQL の簡単なアーキテクチャ図です。ユーザーの SQL ステートメントが MySQL 内でどのように実行されるかを簡単に明確に確認できます。 誰もがこの図を理解できるように、下の図に含まれるいくつかのコンポーネントの基本機能を簡単に紹介します。これらのコンポーネントの機能については、セクション 1.2 で詳しく説明します。コネクタ: ID 認証は (MySQL へのログイン時) 権限に関連します。
クエリ キャッシュ: クエリ ステートメントを実行すると、最初にキャッシュがクエリされます (この機能はあまり実用的ではないため、MySQL 8.0 バージョン以降は削除されました)。
アナライザー: キャッシュがヒットしない場合、SQL ステートメントはアナライザーを通過します。率直に言うと、アナライザーはまず SQL ステートメントが何を行っているかを確認し、次にチェックする必要があります。 SQL ステートメントの構文は正しいですか?
オプティマイザー: MySQL が最適と考えるソリューションに従って実行します。
Executor: ステートメントを実行し、ストレージ エンジンからデータを返します。
簡単に言うと、MySQL は主にサーバー層とストレージ エンジン層に分かれています。サーバー層 : 主にコネクタとクエリが含まれます。キャッシュ、アナライザー、オプティマイザー、エグゼキューターなど。ストアド プロシージャ、トリガー、ビュー、関数など、すべてのクロスストレージ エンジン機能がこの層に実装されます。一般的なログ モジュール binglog ログ モジュールもあります。
ストレージ エンジン: 主にデータの保存と読み取りを担当し、交換可能なプラグイン アーキテクチャを採用し、InnoDB、MyISAM、Memory などの複数のストレージ エンジンをサポートします。エンジンには独自のログ モジュール redolog モジュールがあります。 現在最も一般的に使用されているストレージ エンジンは InnoDB で、MySQL バージョン 5.5.5 以降、デフォルトのストレージ エンジンとして使用されています。
1.2 サーバー層の基本コンポーネントの紹介1) コネクタコネクタは、主に ID 認証と権限に関連する機能に関連しています。ドアマンのような非常に高いレベル。 ユーザー ログイン データベース、ユーザー ID 認証 (アカウント パスワードの検証、権限、その他の操作を含む) を主に担当します。ユーザー アカウントのパスワードが合格した場合、コネクタは権限テーブル内のユーザーのすべての権限を照会します。 , そして、この接続における権限ロジックの判断は、この時に読み取られた権限データに依存します、つまり、接続が切断されない限り、管理者がユーザーの権限を変更しても、ユーザーには影響しません。 2) クエリ キャッシュ (MySQL 8.0 バージョン以降は削除されました)クエリ キャッシュは主に、実行する SELECT ステートメントとステートメントの結果セットをキャッシュするために使用されます。 接続が確立された後、クエリ ステートメントを実行すると、まずキャッシュがクエリされます。MySQL はまず SQL が実行されたかどうかを確認し、キーと値の形式でメモリにキャッシュします。はクエリの推定値、Value は結果セットです。キャッシュ キーがヒットした場合は、クライアントに直接返されます。ヒットしなかった場合は、後続の操作が実行されます。完了後、結果は次の呼び出しを容易にするためにキャッシュされます。もちろん、キャッシュ クエリが実際に実行されるときも、テーブルにクエリ条件があるかどうかを確認するためにユーザーの権限が検証されます。 実際のビジネス シナリオではクエリ キャッシュの失敗が非常に頻繁に発生する可能性があるため、MySQL クエリにキャッシュを使用することはお勧めできません。テーブルを更新すると、このテーブル上のすべてのクエリ キャッシュがクリアされます。頻繁に更新されないデータの場合は、キャッシュを使用することができます。 したがって、一般的に、ほとんどの場合、クエリ キャッシュの使用はお勧めしません。 キャッシュ機能は MySQL バージョン 8.0 以降に削除されましたが、当局もこの機能には実用的な応用シナリオがほとんどないと考えていたため、単純に削除しました。 3) アナライザーMySQL がキャッシュにヒットしない場合は、アナライザーに入ります。アナライザーは主に、SQL ステートメントが何のためのものかを分析するために使用されます。アナライザーはまた、次のように分割されます。ステップ:最初のステップである字句解析、SQL ステートメントは複数の文字列で構成されており、まず、select などのキーワードを抽出し、クエリ テーブルを提案し、提案します。フィールド名、クエリ条件の提案など。これらの操作が完了すると、第 2 ステップに進みます。
2 番目のステップである構文分析 では、主に、入力した SQL が正しく、MySQL の構文に準拠しているかどうかを判断します。
これら 2 つの手順を完了すると、MySQL は実行を開始する準備が整います。しかし、それをどのように実行し、最良の結果を得るにはどうすればよいでしょうか?現時点では、オプティマイザーが機能する必要があります。オプティマイザーの機能は、最適な実行計画であると考えられるものを実行することです (最適でない場合もあります。この記事では、この部分の知識について詳しく説明します) )、たとえば、複数のインデックスがある場合のインデックスの選択方法、複数のテーブルをクエリする場合の関連付け順序の選択方法などです。
オプティマイザを通過した後、このステートメントの具体的な実行が決定されたと言えます。
実行プランを選択すると、MySQL は実行を開始する準備が整います。まず、実行前にユーザーに権限があるかどうかがチェックされます。権限がない場合は、エラーが表示されます。情報に権限がある場合、エンジンのインターフェイスを呼び出し、インターフェイスの実行結果を返します。
ここまで述べましたが、SQL ステートメントはどのように実行されるのでしょうか。実際、SQL は 2 つのタイプに分けることができます。1 つはクエリ、もう 1 つは更新 (追加、更新、削除) です。まずクエリ ステートメントを分析しましょう。ステートメントは次のとおりです:
select * from tb_student A where A.age='18' and A.name=' 张三 ';
上記の説明と組み合わせて、このステートメントの実行プロセスを分析します:
まず、ステートメントにアクセス許可があるかどうかを確認します。権限がない場合は直接エラーメッセージが返されますが、権限がある場合、MySQL8.0以前のバージョンでは、まずキャッシュがクエリされ、このSQL文をキーとしてメモリ上に結果があるかどうかをクエリします。直接キャッシュがある場合は次のステップに進みます。
アナライザーを通じて字句解析を実行し、SQL ステートメントの主要な要素を抽出します。たとえば、上記のステートメントはクエリ選択です。クエリされるテーブル名は tb_student です。すべての列は次のとおりです。クエリ条件は、このテーブルの ID は '1' です。次に、キーワードが正しいかどうかなど、SQL ステートメントに構文エラーがあるかどうかを判断します。問題がない場合は、次のステップに進みます。
次のステップは、オプティマイザが実行計画を決定することです。上記の SQL ステートメントには 2 つの実行計画を含めることができます:
a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。 b.先找出学生中年龄 18 岁的学生,然后再查询姓名为“张三”的学生。
次に、オプティマイザは独自の最適化に従って実行効率を選択します。アルゴリズム 最適なソリューション (オプティマイザは、それが最適でない場合もあると考えます)。実行計画を確認したら、実行を開始する準備が整います。
権限検証を行い、権限がなければエラーメッセージを返し、権限があればデータベースエンジンインターフェースを呼び出し、エンジンの実行結果を返します。上記はクエリ SQL の実行プロセスですが、次に、Update ステートメントがどのように実行されるかを見てみましょう。 SQL ステートメントは次のとおりです:
update tb_student A set A.age='19' where A.name=' 张三 ';
Zhang San の年齢を変更しましょう。年齢フィールドは実際のデータベースには絶対に設定されません。そうしないと、技術担当者に破られてしまいます。実際、各ステートメントは基本的に前のクエリのプロセスに従いますが、更新を実行するときにログを記録する必要があります。これにより、ログ モジュールが導入されます。MySQL 独自のログ モジュール binlog (アーカイブ ログ)、すべてストレージ エンジンを使用することもできます。一般的に使用される InnoDB エンジンには、ログ モジュール redo log (redo log) も付属しています。InnoDB モード プロセスでのこのステートメントの実行について説明します。プロセスは次のとおりです:
最初に Zhang San のデータをクエリします。キャッシュがある場合は、キャッシュも使用されます。 次に、クエリ ステートメントを取得し、年齢を 19 に変更し、エンジン API インターフェイスを呼び出してこのデータ行を書き込みます。InnoDB エンジンはデータをメモリに保存し、同時に REDO ログを記録します。 REDO ログは準備状態になり、実行が完了し、いつでも送信できることを実行者に伝えます。
通知を受信した後、実行プログラムはバイナリログを記録し、エンジンインターフェイスを呼び出して、送信ステータスとして REDO ログを送信します。
アップデートが完了しました。
ここにいる学生の中には、なぜ 1 つのログ モジュールではなく 2 つのログ モジュールを使用する必要があるのかと必ず尋ねるでしょう?
これは、MySQL が InnoDB で動作しなかったためです。エンジン (InnoDB エンジンは他社によってプラグインの形で MySQL に挿入されています) MySQL 独自のエンジンは MyISAM ですが、REDO ログは InnoDB エンジン固有のものであり、他のストレージ エンジンでは利用できないことがわかっています。この結果、クラッシュ セーフ機能が欠如します (クラッシュ セーフ機能があれば、データベースが異常に再起動しても、以前に送信されたレコードは失われません)。Binlog ログはアーカイブにのみ使用できます。
ログ モジュールを 1 つだけ使用できないというわけではありません。InnoDB エンジンが REDO ログを介したトランザクションをサポートしているというだけです。次に、一部の学生は、「2 つのログ モジュールを使用できますが、それほど複雑ではありませんか?」と尋ねるでしょう。なぜ REDO ログにはコミット前の準備状態が導入されるのですか?ここでは、矛盾による証明を使用して、なぜこれを行うのかを説明します。
最初に REDO ログを書き込んで直接送信し、次に binlog を書き込みます。 REDO ログの書き込み後にマシンがハングし、binlog ログが書き込まれないとします。データは REDO ログを通じて復元されますが、bingog はこの時点ではデータを記録しません。後でマシンをバックアップすると、このデータは失われ、マスターとスレーブの同期も失われます。このデータ。
最初にバイナリ ログを書き込み、次に REDO ログを書き込みます。。バイナリ ログの書き込み後にマシンが異常に再起動すると仮定します。REDO ログがないため、マシンはこのレコードを復元できません。しかし、binlog に Record がある場合、上記と同じ理由でデータの不整合が発生します。
REDO ログの 2 段階送信方法を使用する場合は異なりますが、binglog を作成してから REDO ログを送信することで、上記の問題を回避し、データの一貫性を確保できます。そこで問題は、極端な状況はあるのかということです。 REDO ログがコミット前の状態にあり、binglog が書き込まれていると仮定しますが、このときに異常な再起動が発生するとどうなりますか?
これは MySQL の処理機構に依存します MySQL の処理プロセスは次のとおりです:
REDO ログが事前送信されただけでコミット状態ではない場合、この時点でバイナリログが完了しているかどうかが判断され、完了していれば REDO ログが送信され、未完了であればトランザクションが完了します。ロールバックされます。
これにより、データの一貫性の問題が解決されます。
3 つのまとめ
MySQL は主にサーバー層とエンジン層に分かれており、サーバー層には主にコネクタ、クエリ キャッシュ、アナライザー、オプティマイザー、エグゼキュータが含まれます。すべての実行エンジンで共有できるログ モジュール (binlog) もあり、Redolog は InnoDB でのみ使用できます。
エンジン層はプラグインタイプで、現在主にMyISAM、InnoDB、Memoryなどが含まれています。クエリ ステートメントの実行プロセスは次のとおりです。 権限検証 (キャッシュがヒットした場合) ---「クエリ キャッシュ ---」アナライザー ---「オプティマイザー ---」権限検証 ---「エグゼキュータ」 - --》エンジン
以上がMySQL では SQL ステートメントはどのように実行されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。