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を使わない理由

推薦する

HTML doctype の役割の紹介

ドキュメント モードには次の 2 つの機能があります。 1. HTML文書を解析するためにどのHTM...

td セルを結合した場合の td 幅の問題

以下の例では、名前が入っている td の幅が 60px のとき、2 行目の文字数が少ない場合は正常に...

CentOS7 から CentOS8 にアップグレードする方法 (詳細な手順)

この記事では、具体的な例を使用して、CentOS 7 から CentOS 8 にアップグレードする方...

Windows での mysql-5.7.28 のダウンロード、インストール、および構成に関する詳細なグラフィックとテキストのチュートリアル

最近MySQLデータベースのバージョンを変更する必要があり、それを記録するために記事を書きます1. ...

MySQL は、現在のデータ テーブル内のすべての時間に対して指定された時間間隔を増加または減少させます (推奨)

DATE_ADD() 関数は、指定された時間間隔を日付に追加します。現在のテーブル内のすべてのデー...

Vueは完全な選択機能を実装しています

この記事の例では、完全な選択機能を実装するためのVueの具体的なコードを参考までに共有しています。具...

Alibaba Cloud ECS クラウド サーバー (Linux システム) は、MySQL をインストールした後にリモートで接続できません (落とし穴)

昨日、1年間使用していた Alibaba Cloud サーバーを購入しました。システムは Linux...

MySQLの連結関数CONCATの使い方の詳しい説明

前回の記事では、MySQL の置換関数 (Replace) とセグメンテーション関数 (SubStr...

知らないかもしれない実用的なTypeScriptのヒント

目次序文関数のオーバーロードマッピングタイプ部分的、読み取り専用、Null 可能、必須選択、記録除外...

React Nativeはモニタリングジェスチャーの上下プル効果を実現します

React Native は、プルアップとプルダウンの監視ジェスチャを実装します。詳細なコアコードは...

CentOS7 環境での DHCP 設定チュートリアル

目次CentOS7環境での設定コマンド手順1. DHCP設定ファイルを設定する2. グローバル構成を...

Dockerが新しいイメージをロードした後にリポジトリとタグ名が両方ともnoneになる問題を解決する

次のコマンドを使用できます: docker tag [イメージID] [名前]:[バージョン]例えば...

Vue+js 矢印をクリックして画像を切り替える

この記事の例では、矢印をクリックして画像を切り替えるVue + jsの具体的なコードを共有しています...

Docker インストール tomcat dubbo-admin インスタンス スキル

1. tomcatイメージをダウンロードする docker pull tomcat:8.5.29 2...

Raspberry Pi msmtp と mutt のインストールと設定のチュートリアル

1. muttをインストールするsudo apt-get install mutt 2. msmtp...