MySQLクエリ文の実行プロセスの詳細な説明

MySQLクエリ文の実行プロセスの詳細な説明

まず、MySQL がクエリ ステートメントの背後で何を実行しているかを簡単に確認してみましょう。

  • クライアントはサーバーにクエリを送信します。
  • サーバーは最初にクエリ キャッシュをチェックし、キャッシュ ヒットが見つかった場合は、キャッシュに保存されている結果をすぐに返します。それ以外の場合は次の段階に進みます。
  • サーバーは SQL を解析して前処理し、オプティマイザーが対応する実行プランを生成します。
  • MySQL は、ストレージ エンジン API を呼び出して、オプティマイザーによって生成された実行プランに基づいてクエリを実行します。
  • 結果をクライアントに返します。

次に、このプロセスのこれらのステップについて詳しく説明します。

1. クライアントとサーバー間の通信方法

クライアントとサーバー間の通信は半二重通信です。つまり、同時に一方のみが他方にデータを送信できます。したがって、クエリ要求を送信した後、クライアントができることはサーバーがクエリ結果を返すのを待つことだけであり、次のステップに進む前に返されたデータがすべて受信されるまで待つ必要があります。サーバーの送信処理中に送信を中断したり、切断したりすることはできません。

2. クエリキャッシュ

クエリ ステートメントを解析する前に、クエリ キャッシュがオンになっている場合、MySQL はまずクエリがクエリ キャッシュ内のデータにヒットするかどうかを確認します。このチェックは、大文字と小文字を区別するハッシュ テーブルを使用して行われます。クエリがキャッシュにヒットすると、結果はキャッシュから直接取得され、クライアントに返されます。 MySQL は次の操作を実行しなくなります。つまり、クエリ ステートメントは解析されず、実行プランは生成されず、実行もされなくなります。

3. クエリ最適化処理

このリンクは、クエリ実行プロセス全体の中で最も複雑なリンクである可能性があり、SQL 解析、前処理、SQL 実行プランの最適化という 3 つのステップに分けられます。

(1) 構文パーサーと前処理 このプロセスは、渡されたSQL文の構文をチェックし、クエリの権限を検証するためのものです。 Binghui は「解析ツリー」を生成します。

(2)クエリオプティマイザがこのステップに到達すると、ステートメントの構文に問題がないことが証明されます。クエリには、正しい結果を返すことができる実行プランが多数存在する場合があります。この手順では、最適な実行プランを選択します。
MySQL の最適な実行プランはコストに基づいています。 MySQL は、各操作 (where 比較の実行など) のコストを設定し、すべての実行プランから「コスト」が最も低いものを選択します。
次のステートメントを使用して、前のクエリ操作のコストを表示できます。

mysql> SHOW STATUS LIKE 'last_query_cost';

MySQL は実行コストデータを返します:

+-----------------+----------+
| 変数名 | 値 |
+-----------------+----------+
| 最終クエリコスト | 0.549000 |
+-----------------+----------+

ただし、ここでの最小の「コスト」は、クエリ速度が最速であることを意味するわけではないことに注意してください。つまり、「コスト」に基づいてクエリ ステートメントの品質を判断することは、信頼できない場合があります。

オプティマイザの最適化戦略は、静的最適化と動的最適化の 2 種類に大別できます。

静的最適化は、以前に生成された解析ツリーを直接分析します。たとえば、where 条件は、いくつかの代数変換を通じて別の同等の形式に変換できます。静的最適化は、最初の完了後も有効であり、クエリが異なるパラメータで繰り返し実行されても変化しません。これは、一種の「コンパイル(前処理)時の最適化」と考えることができます。

動的最適化はクエリのコンテキストに関連し、クエリが実行されるたびに再評価する必要があります。これは一種の「実行時最適化」と考えることができます。

MySQL が処理できる最適化の種類の一部を次に示します。

  • 関連テーブルの順序を再定義する

場合によっては、指定したクエリ ステートメント内の関連テーブルの順序が、クエリの効率にとって最適ではないことがあります。この場合、MySQL は、関連テーブルの順序を自動的に調整して効率を向上させることができます。

  • 外部結合を内部結合に変換する

すべての OUT JOIN ステートメントを外部結合として実行する必要はありません。 MySQL はこれを認識し、結合の順序を調整するようにクエリを書き換えることができます。

  • 同等の変換規則を使用する

同等のステートメントを使用して比較の数を減らし、常に真である条件や常に真ではない条件をいくつか削除します。たとえば、(5=5 AND a>5) は、(a5 AND b=c AND a=5 の場合、a>5; と書き換えられます。

  • COUNT()、MIN()、MAX() の最適化

インデックスと列の NULL 可能性は、このタイプの式を最適化するのに役立ちます。たとえば、最小値を検索する場合、インデックスを使用して左端のレコードを直接見つけることができます。この方法では、テーブル全体をクエリする必要はなく、代わりに定数に置き換えます。

  • カバーインデックススキャン

インデックス内の列にクエリに必要なすべての列が含まれている場合、MySQL は対応するデータ行をクエリせずに、インデックスを使用して必要なデータを返します。

  • クエリを早期終了する

MySQL は、クエリが要件を満たすことがわかった場合、常にクエリを直ちに終了できます。典型的な例は、LIMIT 句が使用される場合です。

この時点で、MySQL サーバー層は、指定されたクエリ ステートメントに基づいて最適な実行プランを提供します。しかし、これまで実行した一連の操作はすべてサーバー層で実行されており、この層はデータが保存される場所ではないことを知っておく必要があります。したがって、検索のために実際のストレージ エンジンに最適な実行プランを適用する必要があります。これが次のステップ、つまりストレージ エンジンから対応する統計情報を取得することにつながります。

4. クエリ実行エンジン

クエリ最適化フェーズと比較すると、クエリ実行フェーズはそれほど複雑ではありません。 MySQL は実行プランで指定された指示を段階的に実行するだけです。

5. 結果をクライアントに返す

クエリ実行の最後の段階は、結果をクライアントに返すことです。クエリがクライアントに結果セットを返す必要がない場合でも、MySQL はクエリによって影響を受ける行数など、クエリに関するいくつかの情報を返します。
クエリをキャッシュできる場合、MySQL はこの段階でクエリ結果をクエリ キャッシュに格納します。
結果を返すプロセスは段階的かつ漸進的なプロセスです。つまり、最初の結果が取得されると、それがクライアントに返され始めます。これを行う利点は、すべてのデータが一度に返されることがなくなり、メモリの過剰使用が回避され、クライアントができるだけ早く結果を取得できることです。結果セットの各行は、MySQL クライアント/サーバー通信プロトコルに準拠したパケットで送信され、TCP プロトコルを介して送信されます。TCP 送信プロセス中に、パケットがキャッシュされ、バッチで送信されることがあります。

上記はMySQLクエリ文の実行プロセスの詳細な説明です。MySQLクエリ文の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQLはステートメントを詳細に実行します
  • MySQLクエリ文の実行プロセスを理解するための記事
  • DjangoはネイティブのMySQLステートメントを実行してプロセス分析を実装します
  • MySQL ストアド プロシージャで動的 SQL ステートメントを実装する方法
  • SQL文の実行プロセス

<<:  HTML マーキー文字フラグメントのスクロール

>>:  Dockerコンテナにホストディレクトリへの書き込み権限がない場合の解決策

推薦する

Linux での Apache サービスの展開と構成

目次1 Apacheの役割2 Apacheのインストール3. Apacheを有効にする4 Apach...

MySQLdump コマンドを使用した MySQL データの移行

このソリューションの利点はシンプルさと使いやすさですが、欠点はダウンタイムが長くなることです。 した...

webpack -v エラー解決

背景webpackのバージョンを確認したいのですが、webpack -vを実行するとエラーが報告され...

プロセスごとにネットワーク帯域幅を監視する Linux ツール Nethogs のインストールと展開

概要Linux 用のオープン ソース ネットワーク監視ツールは数多くあります。たとえば、帯域幅の使用...

CentOS で新しいユーザーを作成し、キーログインを有効にする方法

目次新しいユーザーを作成する新規ユーザーを承認する新規ユーザーのSSHキーログインを有効にする他のS...

MySQL のデバッグと最適化に関する 101 のヒントを共有する

MySQL は強力なオープンソース データベースです。データベース駆動型アプリケーションの数が増える...

Dockerデータを完全にクリーンアップする方法

目次定期的に剪定するミラーエビクションコンテナのクリーンアップネットワークソート体積の蒸発完全にクリ...

MySQL での %% のようなファジークエリの実装

1、%: 0 個以上の任意の文字を表します。あらゆるタイプと長さの文字に一致します。場合によっては、...

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

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

vue3 プロジェクトを素早く構築し、関連機能を紹介する vite+ts の詳細な説明

目次ヴィテ建てる構成vite.config.tsルーターtsタイプvue3 の知識設定小道具コンテク...

Win7 64 ビット版に MySQL 5.7 をダウンロードしてインストールする際によくある問題の概要

1. 公式ウェブサイトからMySQLをダウンロードします。 これが私たちが探しているものです、win...

Dockerコンテナ内のホストのホスト名が取得できない問題の解決方法

Node.js環境でテストが通っています。他の言語でも同様です。環境変数を取得する方法を使うだけです...

ブラウザ間の hr 区切り文字の違い

Webページを作るときに、区切り線hrを使うことがありますが、IE6やIE7で表示するのは非常に苦痛...

MySQL 5.7.27 のダウンロード、インストール、設定に関する詳細なチュートリアル

目次1. ダウンロード手順2. 環境変数を設定する3. my.iniファイルを設定する4. MySQ...

win2008 サーバー セキュリティ設定の展開ドキュメント (推奨)

私は新年を迎える前からプロジェクトに取り組んでいましたが、ここ数日で、新しいサーバー用に新しく増設し...