ホームページ  >  記事  >  データベース  >  MySQL の実行プロセスとクエリ キャッシュの詳細な紹介

MySQL の実行プロセスとクエリ キャッシュの詳細な紹介

不言
不言転載
2019-04-02 16:36:453059ブラウズ

この記事では、MySQL の実行プロセスとクエリ キャッシュについて詳しく説明します。これには一定の参考値があります。必要な友人は参照できます。お役に立てば幸いです。

MySQL はクエリ プロセスを実行します:
MySQL にリクエストを送信すると、MySQL は正確に何をしますか:

MySQL の実行プロセスとクエリ キャッシュの詳細な紹介

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

mysql は主にサーバー層とストレージ層の 2 つの部分で構成されます。

サーバー層には主に、コネクタ、クエリ キャッシュ、アナライザー、オプティマイザー、エグゼキューターが含まれます。

ストレージ層は主にデータの保存とクエリに使用されます。一般的に使用されるストレージ エンジンには InnoDB や MyISAM などがあります。

(1) MySQL クライアント/サーバー通信プロトコル

MySQL クライアントと通信サーバー間のプロトコルは「半二重」であり、これは、常にサーバーがクライアントにデータを送信しているか、クライアントがサーバーにデータを送信していることを意味します。これら 2 つのアクションは同時に発生することはできません。したがって、メッセージを細かく分割して個別に送信することはできませんし、その必要もありません。

長所と短所:

このプロトコルは MySQL 通信をシンプルかつ高速にしますが、多くの場所で MySQL を制限します。

明らかな制限の 1 つは、これがフロー制御を意味しないことです。一方の端がメッセージの送信を開始すると、もう一方の端はメッセージに応答する前にメッセージ全体を受信する必要があります。これは、ボールを取り戻すゲームのようなものです。いつでも 1 人だけがボールをコントロールでき、ボールをコントロールしている人だけがボールを投げ返す (メッセージを送信する) ことができます。

(2).Connector

MySQL クライアントはサーバーとの接続を確立し、現在接続しているユーザーの権限を取得します


(3)クエリ キャッシュ

クエリ ステートメントを解析する前に、クエリ キャッシュがオンになっている場合、MySQL はキャッシュをチェックしてクエリ キャッシュ内のデータにヒットするかどうかを確認します。このチェックは、大文字と小文字を区別するハッシュ ルックアップによって実装されます。

クエリとキャッシュ内のクエリの間に 1 バイトの違いがあるだけでも、キャッシュされた結果と一致しないため、クエリ
は次の処理段階に入ります。

現在のクエリがクエリ キャッシュにヒットした場合、MySQL はクエリ結果を返す前にユーザー権限を 1 回チェックします。現在のクエリがアクセスする必要があるテーブル情報はクエリ キャッシュにすでに格納されているため、この場合でもクエリ SQL ステートメントを解析する必要はありません。権限に問題がない場合、MySQL は他のすべての段階をスキップし、結果をキャッシュから直接取得してクライアントに返します。この場合、クエリは解析されず、実行プランも生成されず、実行されません。

ps: クエリ キャッシュ機能は、mysql8 以降では利用できなくなっていることに注意してください。非常にクリアしやすいですが命中率は比較的低いです。

(3). Analyzer

キャッシュが見つからないため、SQL文の実行を開始する必要があります。SQL文は実行前に解析する必要があります。

アナライザーは主に SQL ステートメントの構文分析と意味分析を実行し、単語のスペルが間違っているかどうかをチェックし、クエリ対象のテーブルまたはフィールドが存在するかどうかをチェックします。

(4) クエリの最適化

クエリ ライフ サイクルの次のステップは、SQL を実行プランに変換することであり、MySQL はこの実行プランに従ってストレージ エンジンと対話します。これには、SQL の解析、前処理、SQ 実行計画の最適化など、複数のサブフェーズが含まれます。
このプロセスでエラー (構文エラーなど) が発生すると、クエリが終了する可能性があります。

2. クエリ キャッシュについて

(1)
MySQL がキャッシュ ヒットを判断する方法は非常に簡単です: キャッシュは参照テーブルに保存され、ハッシュ値を通じて参照されます。
MySOL クエリ キャッシュは、クエリによって返された完全な結果を保存します。クエリがキャッシュにヒットすると、MySQL は解析、最適化、実行フェーズをスキップして、すぐに結果を返します。

クエリ キャッシュ システムは、クエリに含まれる各テーブルを追跡します。これらのテーブルが変更されると、クエリはキャッシュ システムはこのテーブルで結果を追跡します。関連する保存データはすべて無効になります。

データ テーブルが変更されてもクエリ結果が変わらない可能性が非常に高いため、このメカニズムの効率は比較的低いように見えますが、この単純な実装のコストは非常に小さいため、これは非常に重要です。非常に忙しいシステムです。非常に重要です。

クエリ キャッシュ システムは、アプリケーションに対して完全に透過的です。アプリケーションは、MySQL がクエリ キャッシュから結果を返すか、実際の実行から結果を返すかを気にする必要はありません。実際、これら 2 つの方法の結果はまったく同じです。つまり、キャッシュをクエリするために構文を使用する必要はありません。 MYSQL クエリ キャッシュがオンかオフかは、アプリケーションに対して透過的です。

(2) キャッシュ ヒットの判定

キャッシュ ヒットかどうかを判定する際、MySQL はクエリ ステートメントの解析、「正規化」、またはパラメータ化を行わず、SQL ステートメントを直接使用してクライアントに送信します。 その他送られてくる元の情報にはスペースやコメントなどの異なる文字が含まれており、相違があるとキャッシュの失敗につながります。

クエリ ステートメントに不確実なデータがある場合、そのデータはキャッシュされません。たとえば、関数 NOW() または CURRENT_DATE()
を含むクエリはキャッシュされません。

誤解:
「クエリに未定義の関数が含まれている場合、MySQL はクエリ キャッシュをチェックしない」ということをよく聞きます。この記述は正しくありません。

クエリ キャッシュをチェックするときに SQL ステートメントが解析されていないため、MySQL はクエリ ステートメントにそのような関数が含まれているかどうかを知りません。

クエリ キャッシュをチェックする前に、MySQL は 1 つのことだけを実行します。それは、大文字と小文字を区別しないチェックによって SQL ステートメントが 5EL で始まるかどうかを確認することです。

正確な記述は次のようになります。「クエリ ステートメントに不確実な関数が含まれている場合、キャッシュされた結果をクエリ キャッシュで見つけることは不可能です。」

注:
MySQL のクエリ キャッシュを使用すると、多くの場合、クエリのパフォーマンスが向上しますが、使用する際には特別な注意が必要な問題がいくつかあります。まず、クエリ キャッシュをオンにすると、読み取り操作と書き込み操作の両方で追加の消費が発生します:

1. 読み取りクエリは、
2 を開始する前に、まずキャッシュにヒットするかどうかを確認する必要があります。実行が完了した後、クエリがクエリ キャッシュに存在しないことが MySQL によって検出されると、結果がクエリ キャッシュに保存され、追加のシステム消費が発生します。
3. MySQL はテーブルにデータを書き込むときに、対応するテーブルのすべてのキャッシュを無効にする必要があるため、これは書き込み操作にも影響します。クエリ キャッシュが非常に大きいか断片化している場合、この操作によりシステム消費量が大きくなる可能性があります (クエリ キャッシュに大量のメモリが設定されている場合)

クエリ キャッシュが大量のメモリを使用する場合、キャッシュはこの操作は非常に深刻な問題のボトルネックになる可能性があります
大量のクエリ結果がキャッシュに保存されている場合、キャッシュの無効化操作中にシステム全体がしばらくフリーズする可能性があります

この操作は、グローバル ロック操作保護に依存しているため、操作を実行する必要があるすべてのクエリはこのロックを待機する必要があります。
キャッシュにヒットしたかどうかを検出しているかキャッシュ無効化を検出しているかに関係なく、このグローバル ロックを待機する必要があります。

(3) クエリ キャッシュはどのような状況で役割を果たすことができますか?
理論的には、クエリ キャッシュがオンまたはオフになったときのシステム効率を観察することで、クエリを有効にする必要があるかどうかを判断できます。

多くのリソースを消費する相手のクエリは、通常、キャッシュに非常に適しています。
たとえば、COUNT() などの一部の集計計算クエリは特定のものです。一般に、クエリ キャッシュは複雑な SELECT ステートメントに使用できます。
たとえば、複数テーブルの JOIN の後には並べ替えとページングが必要です。このタイプのクエリは実行するたびに大量のコストを消費しますが、返される結果セットは非常に小さいため、クエリのキャッシュに非常に適しています。

ただし、関係するテーブルに対する UPDATE、DELETE、INSERT 操作は、SELECT に比べて非常に少ないことに注意してください。

クエリ キャッシュが効果的かどうかを判断する直接的なデータは、ヒット率です。クエリ全体に対するクエリ キャッシュから返される結果の割合です。

ただし、キャッシュ ヒット率は判断が難しい値です。良い命中率とは何ですか?特定の状況、特定の分析。

クエリ キャッシュによる効率の向上がクエリ キャッシュによる追加消費量よりも大きい限り、ヒット率が 30% であっても、システム パフォーマンスの向上には大きなメリットがあります。さらに、どのクエリをキャッシュするかも非常に重要です。たとえば、キャッシュされたクエリ自体は大量のコストを消費するため、キャッシュ ヒット率が非常に低い場合でも、システム パフォーマンスには依然として有益です。

キャッシュ ミスの原因は次のとおりです:

1. クエリに不確実な関数 (CURREN_DATE など) が含まれているか、クエリ結果が大きすぎてキャッシュできないため、クエリ ステートメントをキャッシュできません。これにより、ステータス値「キャッシュされていません」が増加します。
2.MySQL はこのクエリを処理したことがないため、結果がキャッシュされたことはありません。

3. もう 1 つの状況は、クエリ結果が以前にキャッシュされていたにもかかわらず、クエリ キャッシュのメモリが使い果たされているため、MySQL が一部のキャッシュを「削除」する必要があるか、データ テーブルが失われているためにキャッシュが無効になる場合です。変更されます。

サーバー上で多数のキャッシュ ミスがあり、実際にはほとんどのクエリがキャッシュされている場合は、次の状況が発生しているはずです:

1. クエリのキャッシュが行われていない完了しましたがウォームアップ中です。言い換えれば、MySQL にはすべてのクエリ結果をキャッシュする機会がありませんでした。
2. クエリ ステートメントはこれまでに実行されたことがありません。アプリケーションがクエリ ステートメントを繰り返し実行しない場合、ウォームアップが完了した後でも多くのキャッシュ ミスが発生します。
3. キャッシュ無効化操作が多すぎます。

(4) クエリ キャッシュの設定と保​​守方法

query_cache_type

クエリ キャッシュをオンにするかどうか。 0FNまたはDEMANDに設定できます。 DEMAND は、クエリ ステートメント内で SQL_CACHE を明確に示すステートメントのみがクエリ キャッシュに配置されることを意味します。この変数は、セッション レベルまたはグローバル レベルにすることができます。

#query_cache_size

クエリ キャッシュによって使用される合計メモリ領域 (バイト単位)。この値は 1024 の整数倍である必要があります。そうでない場合、MySQL によって割り当てられる実際のデータは、指定したものとわずかに異なります。


query_cahce_min_res_unit

クエリ キャッシュにメモリ ブロックを割り当てるときの最小単位。


query_chache_limit

MySQL がキャッシュできるクエリ結果の最大数。クエリ結果がこの値より大きい場合、キャッシュされません。クエリ キャッシュはデータの生成時にデータのキャッシュを開始するため、すべての結果が返されて初めてクエリ結果が制限を超えているかどうかを知ることができます。

超えた場合、MySQL は制限を増やします。ステータス値 Cache_not_cached と will クエリキャッシュから結果が削除される このような状況が多いことが事前にわかっている場合は、クエリ文に

## を追加することをお勧めします (5) 代替案

MySQL クエリ キャッシュ作業の原則は次のとおりです: 実行 クエリを実行する最も速い方法はクエリを実行しないことですが、それでもクエリをサーバーに送信する必要があり、サーバーはまだ少し作業を行う必要があります。一部のクエリでサーバーと通信する必要がない場合はどうなりますか? 現時点では、クライアントのキャッシュは、MySQL サーバーへの負荷を大幅に分散するのに役立ちます

#概要:

まったく同じ クエリが繰り返し実行される場合、クエリ キャッシュはデータベースで再実行することなく、ただちに結果を返すことができます。私たちの経験によれば、同時実行性が高い環境でキャッシュにクエリを実行すると、システムのパフォーマンスが低下したり、フリーズしたりすることがあります。

クエリ キャッシュを使用する必要がある場合は、あまり多くのメモリを設定せず、利点が確認された場合にのみ使用してください。

クエリ キャッシュを使用するかどうかを判断するには、Percona サーバーを使用し、より詳細なログを観察し、簡単な計算を行うことをお勧めします。また、キャッシュ ヒット率 (必ずしも役立つわけではありません)、「NSERTS 対 SELECT 比率」(このパラメーターも直感的ではありません)、または「ヒット対書き込み比率」(この参照の方が意味があります) を確認することもできます。

クエリ キャッシュは、アプリケーションに対して完全に透過的で、追加のコーディングを必要としない非常に便利なキャッシュですが、より高いキャッシュ効率が必要な場合は、キャッシュまたは他の同様のソリューションを使用することをお勧めします。

【関連する推奨事項:

MySQL ビデオ チュートリアル

]

以上がMySQL の実行プロセスとクエリ キャッシュの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。