1. 論理アーキテクチャの分析
1.1 レイヤ 1: 接続層
システム (クライアント) がMySQL
サーバーにアクセスする前に、最初にTCP
接続を確立します。
3 ウェイ ハンドシェイクによって接続が正常に確立されると、MySQL
サーバーは、TCP
転送されたアカウント パスワードに対して ID 認証と権限の取得を実行します。
- ユーザー名またはパスワードが間違っている場合、「ユーザーのためアクセスが拒否されました」エラーが表示され、クライアント プログラムは実行を終了します。
- ユーザー名とパスワードの認証が通ると、そのアカウントとコネクションが持つ権限が権限テーブルから検索され、その後の権限判定ロジックはこの時に読み取られた権限に依存します。
TCP
接続がリクエストを受信した後、このクライアントとの対話専用のスレッドにそのリクエストを割り当てる必要があります。したがって、後続のプロセスを実行するためのスレッドプールが存在します。各接続はスレッド プールからスレッドを取得するため、スレッドの作成と破棄のオーバーヘッドが排除されます。
1.2 レイヤ 2: サービス レイヤ
-
SQLインターフェース: SQLインターフェース
- ユーザーの SQL コマンドを受け取り、ユーザーがクエリする必要がある結果を返します。たとえば、SELECT ... FROM は SQL インターフェイスを呼び出します。
- MySQL は、DML (データ操作言語)、DDL (データ定義言語)、ストアド プロシージャ、ビュー、トリガー、カスタム関数などの複数の SQL 言語インターフェイスをサポートしています。
-
パーサー: パーサー
- パーサーで SQL ステートメントの構文分析と意味分析を実行します。SQL ステートメントをデータ構造に分解し、この構造を後続のステップに渡します。その後の SQL ステートメントの配信と処理は、この構造に基づいています。分解中にエラーが発生した場合は、SQL ステートメントが不当であることを意味します。
- SQL コマンドがパーサーに渡されると、パーサーによって検証および解析されて作成され
语法树
、クエリ構文ツリーがデータ ディクショナリに従って強化されます验证该客户端是否具有执行该查询的权限
。構文ツリーの作成後、MySQL は SQL クエリの構文も最適化し、クエリを書き換えます。
-
オプティマイザー: クエリ オプティマイザー
- SQL ステートメントが解析された後、クエリの前に、クエリ オプティマイザーを使用して SQL ステートメントの実行パスが決定され、
执行计划
. - この実行計画には、クエリを
使用哪些索引
実行するかどうか(テーブル全体の取得かインデックスの取得か)、テーブル間の接続順序が示されており、最後に実行計画の手順に従ってストレージ エンジンが提供するメソッドが呼び出され、実際に実行されます。クエリを実行し、クエリ結果をユーザーに返します。 - クエリには"
选取-投影-连接
" 戦略が使用されます。例えば:
SELECT id,name FROM student WHERE gender = '女';
选取
この SELECT クエリは、すべてのテーブルをクエリしてから性別フィルタリングを実行するのではなく、最初に WHERE ステートメントに基づいて実行されます。投影
この SELECT クエリは、すべての属性を抽出してからフィルタリングするのではなく、最初に id と name に基づいて属性を実行し、连接
これら 2 つのクエリ条件を組み合わせて最終的なクエリ結果を生成します。 - SQL ステートメントが解析された後、クエリの前に、クエリ オプティマイザーを使用して SQL ステートメントの実行パスが決定され、
-
キャッシュとバッファ: クエリ キャッシュ コンポーネント
- MySQL は内部的にいくつかのキャッシュとバッファを維持します。たとえば、クエリ キャッシュは SELECT ステートメントの実行結果をキャッシュするために使用されます。対応するクエリ結果がその中に見つかる場合は、クエリ解析のプロセス全体を実行する必要はありませんクエリ キャッシュは、SELECT ステートメントの実行結果をキャッシュするために使用され、結果はクライアントにフィードバックされます。
- このキャッシュ メカニズムは、一連の小さなキャッシュで構成されます。たとえば、テーブル キャッシュ、レコード キャッシュ、キー キャッシュ、権限キャッシュなどです。
- このクエリ キャッシュは で使用できます
不同客户端之间共享
。 - MySQL 5.7.20 以降、クエリ キャッシュは非推奨になり、 で使用できるようになりました
MySQL 8.0中删除
。
1.3 レイヤ 3: エンジン層
プラグイン ストレージ エンジン層 (ストレージ エンジン) は、MySQL でのデータの保存と取得を真に担当し、物理サーバー レベルで維持される基盤となるデータに対して操作を実行します。サービス層は、API を介してストレージ エンジンと通信します。
1.4 概要
3 層構造に単純化すると、次のようになります。
-
接続層: クライアントとサーバーは接続を確立し、クライアントは SQL をサーバーに送信します。
-
SQL層(サービス層):SQL文のクエリ処理を実行しますが、データベースファイルの保存方法とは関係ありません。
-
ストレージ エンジン層: データベース ファイルを処理し、データの保存と読み取りを担当します。
2. SQL実行処理
2.1 MySQL での SQL 実行プロセス
MySQL クエリ プロセス:
1. クエリ キャッシュ: サーバーは、クエリ キャッシュ内でこの SQL ステートメントを見つけた場合は、結果を直接クライアントに返しますが、そうでない場合は、パーサー ステージに入ります。クエリ キャッシュは多くの場合非効率であるため、この機能は MySQL 8.0 以降廃止されたことに注意してください。
クエリ キャッシュはクエリ結果を事前にキャッシュするので、次回実行することなく結果を直接取得できます。MySQL のクエリ キャッシュはクエリ プランをキャッシュするのではなく、クエリの対応する結果をキャッシュすることに注意してください。これは、クエリが鲁棒性大大降低
のみに一致することを意味します相同的查询操作才会命中查询缓存
。2 つのクエリ リクエスト間の文字の違い (スペース、コメント、大文字小文字など) があると、キャッシュが失われる原因になります。したがって、MySQL のクエリ キャッシュのヒット率は高くありません。
同時に、クエリ リクエストに特定のシステム関数、ユーザー定義の変数と関数、および一部のシステム テーブル (mysql、information_schema、および Performance_schema データベース内のテーブルなど) が含まれている場合、リクエストはキャッシュされません。
また、キャッシュなのであります缓存失效的时候
。MySQL のキャッシュ システムは、関係する各テーブルを監視します。テーブル上で 、 、 、 、 、またはステートメントを使用するなど、テーブルの構造またはデータが変更されている限り、そのテーブルを使用するキャッシュされたクエリはすべて無効になり、INSERT
キャッシュUPDATE
からDELETE
削除TRUNCATE TABLE
されALTER TABLE
ます。!の場合、クエリ キャッシュのヒット率は非常に低くなります。DROP TABLE
DROP DATABASE
更新压力大的数据库
2. パーサー: パーサーで SQL ステートメントの構文分析と意味分析を実行します。
アナライザーは词法分析
最初に「」を実行します。入力するのは複数の文字列とスペースで構成される SQL ステートメントであり、MySQL はその中の文字列が何であるか、またそれが何を表しているかを識別する必要があります。MySQL は、入力された「select」キーワードから、これがクエリ ステートメントであることを認識します。また、文字列「T」を「テーブル名 T」として、文字列「ID」を「列 ID」として認識する必要があります。
次に「语法分析
」を実行します。構文解析 (Bison など) は、字句解析の結果に基づいて、入力された SQL ステートメントが文法規則に従って有効であるかどうかを判断します满足 MySQL 语法
。SQL ステートメントが正しい場合は、構文ツリーが生成されます。
3. オプティマイザー: オプティマイザーは、SQL ステートメントの実行パス ( に基づくか全表检索
、に基づくか索引检索
など)を決定します。クエリ オプティマイザーでは、逻辑查询
最適化フェーズと物理查询
最適化フェーズに分けることができます。
4. 実行者: 実行する前に、ユーザーが であるかどうかを判断する必要があります具备权限
。そうでない場合は、権限エラーが返されます。権限がある場合は、SQL クエリを実行して結果を返します。MySQL 8.0 より前のバージョンでは、クエリ キャッシュが設定されている場合、クエリ結果はキャッシュされます。
MySQL における SQL ステートメントの流れは、SQL ステートメント → クエリ キャッシュ → パーサー → オプティマイザー → エグゼキューターです。
3. データベースバッファプール(バッファプール)
InnoDB
ストレージ エンジンはストレージ領域をページ単位で管理し、追加、削除、変更、クエリ操作は基本的にページへのアクセス (ページの読み取り、ページの書き込み、新しいページの作成など) となります。ディスク I/O には多くの時間がかかり、メモリ内の操作はより効率的になります。データ テーブルまたはインデックス内のデータをいつでも利用できるようにするために、DBMS は実際にページにアクセスする前にデータを適用します占用内存来作为数据缓冲池
。ディスク上のページは、Buffer Pool
メモリにキャッシュされた後にのみアクセスできます。
この利点は、ディスクのアクティビティを最小限に抑えられることです减少与磁盘直接进行 I/O 的时间
。ご存知のとおり、この戦略は SQL ステートメントのクエリ パフォーマンスを向上させるために非常に重要です。インデックス付きデータがバッファー プール内にある場合、アクセスのコストは大幅に削減されます。
3.1 バッファプール と クエリキャッシュの比較
1. バッファプール
この図から、InnoDB バッファ プールにはデータ ページ、インデックス ページ、挿入バッファ、ロック情報、アダプティブ ハッシュ、データ ディクショナリ情報などが含まれていることがわかります。
キャッシュの原則:
" 位置 * 频次
"この原則は、I/O アクセス効率の最適化に役立ちます。
まず効率を決めるのは場所ですが、メモリ上のデータに直接アクセスできるようにバッファプールが用意されています。
次に、頻度によって優先順位が決まります。バッファー プールのサイズには制限があるため、たとえば、ディスクには 200G がありますが、メモリは 16G しかなく、バッファー プールのサイズは 1G しかないため、すべてのデータをバッファー プールにロードすることはできません。 、優先順位が関係します优先对使用频次高的热数据进行加载
。
2. クエリキャッシュ
查询结果缓存
クエリキャッシュは、次回実行せずに直接結果を取得できるように事前に設定されます。MySQL のクエリ キャッシュはクエリ プランをキャッシュするのではなく、クエリの対応する結果をキャッシュすることに注意してください。ヒット条件が厳しく、データテーブルが変更されるとクエリキャッシュが無効になるため、ヒット率が低くなります。
3.2 バッファプールからデータを読み取る方法
バッファ プール マネージャは、頻繁に使用されるデータを保存しようとします。データベースがページを読み取るとき、最初にページがバッファ プール内にあるかどうかを判断します。存在する場合は直接読み取ります。存在しない場合は、メモリを通じてそれを読み取るか、ディスクがバッファ プールにページを保存してからそれを読み取ります。
3.3 バッファプールのサイズを表示/設定する
バッファプールサイズの表示
show variables like 'innodb_buffer_pool_size';
バッファプールサイズの設定
set global innodb_buffer_pool_size = 268435456;
または
[server]
innodb_buffer_pool_size = 268435456
3.4 複数のバッファプールインスタンス
[server]
innodb_buffer_pool_instances = 2
バッファプール数の確認方法
show variables like 'innodb_buffer_pool_instances';
各インスタンスBuffer Pool
が占有する実際のメモリ空間
innodb_buffer_pool_size/innodb_buffer_pool_instances