MySQLクライアントとサーバーのプロトコルの解釈

MySQLクライアントとサーバーのプロトコルの解釈

MySQL サーバーから高いパフォーマンスを得る必要がある場合、最善の方法は、MySQL がクエリを最適化して実行する仕組みを時間をかけて研究することです。これらを理解すると、ほとんどのクエリ最適化は十分に根拠のあるものとなり、クエリ最適化プロセス全体がより論理的になります。次の図は、MySQL がクエリを実行するプロセスを示しています。

  1. クライアントは SQL ステートメントをサーバーに送信します。
  2. サーバーはクエリ キャッシュをチェックします。キャッシュにデータがある場合は、キャッシュされた結果が直接返されます。それ以外の場合は、SQL ステートメントが次のリンクに渡されます。
  3. サーバーは SQL ステートメントを解析、前処理、最適化した後、それをクエリ オプティマイザーに渡してクエリ プランを形成します。
  4. クエリ実行エンジンは、ストレージ エンジン インターフェイスを呼び出してクエリ プランを実行します。
  5. サーバーはクエリの結果をクライアントに返します。

上記の手順はすべて複雑なので、次のいくつかの記事で各リンクについて詳しく説明します。クエリの最適化プロセスは特に複雑であり、理解することが重要です。

MySQL クライアント/サーバー プロトコル

MySQL クライアント/サーバー プロトコルの内部詳細を理解する必要はありませんが、高アプリケーション レベルでどのように動作するかを理解する必要があります。このプロトコルは半二重であるため、MySQL サーバーは同時にメッセージを送受信できず、メッセージを複数の短いメッセージに分割することもできません。このメカニズムにより、MySQL 通信がシンプルかつ高速になりますが、一方でいくつかの制限も追加されます。たとえば、これはフロー制御が不可能であり、一方がメッセージを送信すると、もう一方は応答する前にメッセージ全体を受信する必要があることを意味します。それは、前後に卓球をするようなものです。一度にボールを持っているのは片側だけで、ボールを受け取ったときだけ、それを打ち返すことができます。

クライアントはクエリを単一のパケットでサーバーに送信するため、クエリが大きい場合は max_allowed_pa​​cket を構成することが重要です。クライアントがクエリを送信すると、結果が返されるのを待つだけです。

対照的に、サーバーの応答は通常、複数のパケットで構成されます。サーバーが応答したら、クライアントは結果セット全体を取得する必要があります。クライアントは、単に数行を取得して、残りのデータを送信しないようにサーバーに指示することはできません。クライアントがデータの最初の数行のみを返す必要がある場合、サーバーがすべてのデータを返すまで待機し、不要なデータを破棄するか、または接続を切断するしかありません。どちらの方法も適切な選択ではないため、適切な LIMIT 句が非常に重要です。

ほとんどの MySQL 接続ライブラリは、結果セット全体をフェッチしてメモリにキャッシュすること、または必要なデータ行をフェッチすることをサポートしています。通常、デフォルトの動作では、結果セット全体をフェッチし、メモリにキャッシュします。要求されたすべての行が返されるまで、MySQL サーバーはこのクエリのロックとリソースを解放しないため、これを知っておくことは重要です。ほとんどのクライアント ライブラリでは、データがサーバーから取得されているように見えますが、実際にはデータはキャッシュから読み取られるだけの場合もあります。これはほとんどの場合問題ありませんが、長い時間がかかったり、大量のメモリを占有したりする大規模なデータクエリには適していません。クエリ結果をキャッシュしないように指定すると、メモリ使用量が少なくなり、結果をより速く処理できます。この方法の欠点は、クエリ中にサーバー側のロックとリソースの使用が発生することです。

PHP を例にとると、PHP でよく使用されるクエリ コードは次のとおりです。

<?php
$link = mysql_connect('localhost', 'ユーザー', 'パスワード');
$result = mysql_query('SELECT * FROM huge_table', $link);
($row = mysql_fetch_array($result)) の間 {
  //データ結果を処理中}

?>

このコードは必要な行だけを取得しているように見えます。ただし、このクエリは実際には、mysql_query を呼び出した後にすべての結果をメモリに格納します。 while ループは実際にはメモリ内のデータを反復します。逆に、mysql_query の代わりに mysql_unbuffered_query を使用すると、結果はキャッシュされません。

<?php
$link = mysql_connect('localhost', 'ユーザー', 'パスワード');
$result = mysql_unbuffered_query('SELECT * FROM huge_table', $link);
($row = mysql_fetch_array($result)) の間 {
  //データ結果を処理中}

?>

プログラミング言語によって、キャッシュの上書きの処理方法が異なります。たとえば、Perl DBD::mysql ドライバーでは、次に示すように、mysql_use_result 属性を通じて C 言語クライアント ライブラリ (デフォルトは mysql_buffer_result) を指定する必要があります。

パーレル

DBI を使用します。
my $dbn = DBI->connect('DBI:mysql:;host=localhost', 'user', 'password');
私の $sth = $dbn->prepare('SELECT * FROM huge_table', {mysql_use_result => 1});
$sth->execute();
(私の$row = $sth->fetchrow_array()) {
	#データ結果を処理中}

prepare は結果をキャッシュするのではなく使用するように指定することに注意してください。接続時に指定することもできますが、その場合、各クエリはキャッシュされません。

my $dbn = DBI->connect('DBI:mysql:;mysql_use_result=1;host=localhost', 'user', 'password');

上記は、MySQL クライアントおよびサーバー プロトコルの詳細な解釈です。MySQL クライアントおよびサーバー プロトコルの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL mysqladmin クライアントの使用の概要
  • MySQL は対応するクライアント プロセスにどのように接続しますか?
  • MySql クライアントが数秒で終了する問題を解決する (my.ini が見つからない)
  • PHP Swoole 非同期 MySQL クライアント実装例
  • Node.js mysqlクライアントが認証プロトコルをサポートしていない問題を解決する
  • mysql8.0.11クライアントがログインできない問題の解決方法
  • 絵文字と問題解決のためのMySQL/Javaサーバーサポートの詳細な説明
  • NodeJS サーバー開発入門 (Express+MySQL)
  • アプリケーション サーバー用の MySQL 接続プール (高い同時実行性をサポート)

<<:  JavaScript タイマーの詳細

>>:  GoogleとFacebookがDockerを使わない理由

推薦する

VMware に Centos8 をインストールする詳細なチュートリアル

CentOS公式サイトアドレスhttps://www.centos.org/まず必要なファイルをダウ...

Linux でハイパースレッディング技術を動的に有効/無効にする方法の詳細な説明

序文Intel のハイパースレッディング テクノロジーにより、1 つの物理コア上で 2 つのスレッド...

Nginx で https をアップグレードする方法

購入証明書Alibaba CloudのCloud Shield証明書サービスから購入できます。証明書...

見落としがちなMySQLのCOLLATIONの例の詳細な説明

序文MySQL データベースの文字列型は、CHAR、VARCHAR、BINARY、BLOB、TEXT...

MySQL の null (IFNULL、COALESCE、NULLIF) に関する知識ポイントのまとめ

この記事では、MySQL の null (IFNULL、COALESCE、NULLIF) に関連する...

中国語でのNginx設定パラメータの詳細な説明(負荷分散とリバースプロキシ)

PS: 最近、nginx を詳細に紹介している <<High-Performance ...

KVM ベースの SRIOV パススルー構成とパフォーマンス テストの詳細な説明

SRIOVの導入、VFパススルー構成、パケット転送速度性能テスト目次1. SRIOVの紹介2. 環境...

Dockerコンテナを使用する簡単な例

目次1. イメージをプルする2. イメージを実行する3. コンテナ内でアプリケーションをテストする4...

MySQL で主キーと ROWID を使用する際の落とし穴の概要

序文MySQL の rowid の概念については聞いたことがあるかもしれませんが、テストや実践が難し...

docker runとstartの違い

docker における実行と開始の違いDocker run はミラーイメージを指定します。そしてdo...

Dockerコンテナ内でホストDocker操作を呼び出して実行する

まず、この投稿は Docker 初心者向けです。もちろん、ベテランであれば記事中の分割線以降の操作方...

CSS3セレクターの新機能の実装

目次基本的なセレクタ拡張属性セレクタ疑似クラスと疑似要素セレクター基本的なセレクタ拡張1. 子要素セ...

JavaScript 日付ツールの概要

ユーティリティ = { /** * 死亡年ですか? * @return {Boolse} true...

検索エンジンのウェブサイトの入り口の無料コレクション

1: Baiduウェブサイトログイン入口ウェブサイト: http://www.baidu.com/s...

CSS を使用して fullpage.js のフルスクリーン スクロール効果を実装するサンプル コード

最近 CSS を勉強していたとき、 2 つの CSS プロパティだけを使用して全画面スクロール効果を...