検索
ホームページバックエンド開発PHPチュートリアルMySQL のクエリに関する PHP 同時実行の例 (図)

この記事では主にMySQLのPHP同時クエリのサンプルコードを紹介していますが、編集者が非常に良いと思ったので、参考として共有させていただきます。エディターをフォローして見てみましょう

私は最近 PHP を勉強していて、とても気に入っています。PHP での MySQL の同時クエリの問題に遭遇しました。ちなみに、勉強してメモを残しました。 query

これは最も一般的なものです。呼び出しモードでは、クライアントは Query[関数] を呼び出し、クエリ コマンドを開始し、結果が返されるのを待って、結果を読み取り、次に 2 番目のクエリ コマンドを送信し、返される結果を取得し、その結果を読み取ります。所要時間の合計は、2 つのクエリの時間の合計になります。たとえば、以下に示すようにプロセスを簡略化します。

サンプル画像、1.1 から 1.3 は Query [関数] の呼び出しです。2 つのクエリは 1.1、1.2、1.3、2.1、2.2、2.3 を通過します。特に 1.2 と 2.2 では、ブロックされて待機し、プロセスは他のことを行うことができません。

同期呼び出しの利点は、直感的な考え方に準拠しており、呼び出しと処理が簡単であることです。欠点は、結果が返されるのを待ってプロセスがブロックされ、実行時間が余分にかかることです。
複数のクエリリクエストがある場合、またはプロセスが他の処理を行っている場合、待ち時間を合理的に利用してプロセスの処理能力を向上させることは可能ですか?


分割

次に、Query [関数] を分割します。クライアントは 1.1 の直後に戻り、1.2 をスキップして 1.3 にデータが到着した後にデータを読み取ります。このようにして、プロセスは元の 1.2 の段階から解放され、別の SQL クエリ [2.1] を開始するなど、より多くのことを実行できるようになります。並行クエリのプロトタイプを見たことがありますか?

同時クエリ

同期クエリと比較して、同時クエリでは、前のクエリリクエストが開始された直後に次のクエリリクエストを開始できます。以下に示すように、プロセスを簡略化します。

例の図では、1.1.1 でリクエストが正常に送信された後、すぐに [1.1.2] が返され、最終的なクエリ結果がリモート 1.2 で返されます。ただし、1.1.1 と 1.2 の間では、この期間中に 2 つのクエリ リクエストが同時に開始され、2.2 は 1.2 よりも前に到着したため、2 つのクエリの合計時間は の時間と同じでした。最初のクエリ。

同時クエリの利点は、プロセスの使用率を向上させ、サーバーによるクエリの処理のブロックと待機を回避し、複数のクエリの時間を短縮できることです。ただし、欠点も明らかです。N 個の同時クエリを開始するには、データベース接続プールを備えたアプリケーションの場合、この状況を回避できます。

縮退

理想的には、N 個のクエリを同時に実行し、合計の消費時間はクエリ時間が最も長いクエリと同じになるようにする必要があります。ただし、同時クエリが [同期クエリ] に [縮退] する可能性もあります。何?例の図では、2.1.1 より前に 1.2 が返された場合、同時クエリは [同期クエリ] に [縮退] しますが、コストは同期クエリよりも高くなります。

多重化

クエリ1を開始
  • クエリ2を開始
  • クエリ3を開始
  • クエリ1を待機中、クエリ2. Query3
  • はquery2の結果を読み取ります
  • クエリ 1 の結果を読む
  • クエリ 3 の結果を読む
  • では、クエリ結果がいつ返されるか、どのクエリ結果が返されるかを知るには、どうやって待つのでしょうか?

クエリ IO ごとに read を呼び出しますか?ブロッキング IO が発生した場合、1 つの IO でブロックされ、他の IO では結果が返され、処理できなくなります。したがって、ノンブロッキング IO の場合、いずれかの IO がブロックされることを心配する必要はありません。ただし、ポーリングと判定が継続的に発生し、CPU リソースが浪費されます。

この状況では、多重化を使用して複数の IO をポーリングできます。

PHP は MySQL を実装します

PHP の mysqli (mysqlnd ドライバー) は、多重ポーリング IO (mysqli_poll) と非同期クエリ (MYSQLI_ASYNC、mysqli_reap_async_query) を提供します。サンプル コード:

<?php
 $sqls = array(
  &#39;SELECT * FROM `mz_table_1` LIMIT 1000,10&#39;,
  &#39;SELECT * FROM `mz_table_1` LIMIT 1010,10&#39;,
  &#39;SELECT * FROM `mz_table_1` LIMIT 1020,10&#39;,
  &#39;SELECT * FROM `mz_table_1` LIMIT 10000,10&#39;,
  &#39;SELECT * FROM `mz_table_2` LIMIT 1&#39;,
  &#39;SELECT * FROM `mz_table_2` LIMIT 5,1&#39;
 );
 $links = [];
 $tvs = microtime();
 $tv = explode(&#39; &#39;, $tvs);
 $start = $tv[1] * 1000 + (int)($tv[0] * 1000);
 // 链接数据库,并发起异步查询
 foreach ($sqls as $sql) { 
  $link = mysqli_connect(&#39;127.0.0.1&#39;, &#39;root&#39;, &#39;root&#39;, &#39;dbname&#39;, &#39;3306&#39;);
  $link->query($sql, MYSQLI_ASYNC); // 发起异步查询,立即返回
  $links[$link->thread_id] = $link;
 }
 $llen = count($links);
 $process = 0;
 do {
  $r_array = $e_array = $reject = $links;
  // 多路复用轮询IO
  if(!($ret = mysqli_poll($r_array, $e_array, $reject, 2))) {
   continue;
  }
  // 读取有结果返回的查询,处理结果
  foreach ($r_array as $link) {
   if ($result = $link->reap_async_query()) {
    print_r($result->fetch_row());
    if (is_object($result))
     mysqli_free_result($result);
   } else {
   }
   // 操作完后,把当前数据链接从待轮询集合中删除
   unset($links[$link->thread_id]);
   $link->close();
   $process++;
  }
  foreach ($e_array as $link) {
   die;
  }
  foreach ($reject as $link) {
   die;
  }
 }while($process < $llen);
 $tvs = microtime();
 $tv = explode(&#39; &#39;, $tvs);
 $end = $tv[1] * 1000 + (int)($tv[0] * 1000);
 echo $end - $start,PHP_EOL;

mysqli_poll ソースコード:

#ifndef PHP_WIN32
#define php_select(m, r, w, e, t) select(m, r, w, e, t)
#else
#include "win32/select.h"
#endif
/* {{{ mysqlnd_poll */
PHPAPI enum_func_status
mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, int * desc_num)
{
 struct timeval tv;
 struct timeval *tv_p = NULL;
 fd_set   rfds, wfds, efds;
 php_socket_t max_fd = 0;
 int    retval, sets = 0;
 int    set_count, max_set_count = 0;
 DBG_ENTER("_mysqlnd_poll");
 if (sec < 0 || usec < 0) {
  php_error_docref(NULL, E_WARNING, "Negative values passed for sec and/or usec");
  DBG_RETURN(FAIL);
 }
 FD_ZERO(&rfds);
 FD_ZERO(&wfds);
 FD_ZERO(&efds);
 // 从所有mysqli链接中获取socket链接描述符
 if (r_array != NULL) {
  *dont_poll = mysqlnd_stream_array_check_for_readiness(r_array);
  set_count = mysqlnd_stream_array_to_fd_set(r_array, &rfds, &max_fd);
  if (set_count > max_set_count) {
   max_set_count = set_count;
  }
  sets += set_count;
 }
 // 从所有mysqli链接中获取socket链接描述符
 if (e_array != NULL) {
  set_count = mysqlnd_stream_array_to_fd_set(e_array, &efds, &max_fd);
  if (set_count > max_set_count) {
   max_set_count = set_count;
  }
  sets += set_count;
 }
 if (!sets) {
  php_error_docref(NULL, E_WARNING, *dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
  DBG_ERR_FMT(*dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
  DBG_RETURN(FAIL);
 }
 PHP_SAFE_MAX_FD(max_fd, max_set_count);
 // select轮询阻塞时间
 if (usec > 999999) {
  tv.tv_sec = sec + (usec / 1000000);
  tv.tv_usec = usec % 1000000;
 } else {
  tv.tv_sec = sec;
  tv.tv_usec = usec;
 }
 tv_p = &tv;
 // 轮询,等待多个IO可读,php_select是select的宏定义
 retval = php_select(max_fd + 1, &rfds, &wfds, &efds, tv_p);
 if (retval == -1) {
  php_error_docref(NULL, E_WARNING, "unable to select [%d]: %s (max_fd=%d)",
      errno, strerror(errno), max_fd);
  DBG_RETURN(FAIL);
 }
 if (r_array != NULL) {
  mysqlnd_stream_array_from_fd_set(r_array, &rfds);
 }
 if (e_array != NULL) {
  mysqlnd_stream_array_from_fd_set(e_array, &efds);
 }
 // 返回可操作的IO数量
 *desc_num = retval;
 DBG_RETURN(PASS);
}

同時クエリ操作の結果

効果をより直感的に確認するために、操作用に最適化されていない 1 億 3,000 万のデータ量を持つテーブルを見つけました。

同時クエリの結果:

同期クエリの結果:

この結果から、同期クエリの合計消費時間は、すべてのクエリの時間の合計です。同時クエリの消費量は実際に最も長いクエリです (同期クエリの 4 番目のクエリには数秒かかりますが、これは同時クエリの合計時間と一致します)。また、同時クエリのクエリ順序は次のクエリとは異なります。結果が到着する順序。

クエリ時間が短い複数のクエリの比較

クエリ時間が短い複数の SQL クエリを使用して比較します

同時クエリのテスト 1 結果 (データベースリンク時間もカウントされます):

同期の結果クエリ (データベース リンク時間もカウントされます):

同時クエリのテスト 2 の結果 (データベース リンク時間はカウントされません):

結果から判断すると、同時クエリ テスト1は恩恵を受けませんでした。同期クエリの観点から見ると、各クエリには約 3 ~ 4 ミリ秒かかります。ただし、データベース接続時間が統計に含まれていない場合 (同期クエリにはデータベース接続が 1 つしかありません)、同時クエリの利点が再び反映される可能性があります。

結論

ここでは、PHP での同時クエリ MySQL の実装について説明し、実験結果から同時クエリの長​​所と短所を直観的に理解しました。データベース接続を確立する時間が、最適化された SQL クエリの大部分を占めます。 #接続プールがないのですが、何に使いますか

以上がMySQL のクエリに関する PHP 同時実行の例 (図)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPの現在のステータス:Web開発動向を見てくださいPHPの現在のステータス:Web開発動向を見てくださいApr 13, 2025 am 12:20 AM

PHPは、現代のWeb開発、特にコンテンツ管理とeコマースプラットフォームで依然として重要です。 1)PHPには、LaravelやSymfonyなどの豊富なエコシステムと強力なフレームワークサポートがあります。 2)パフォーマンスの最適化は、Opcacheとnginxを通じて達成できます。 3)PHP8.0は、パフォーマンスを改善するためにJITコンパイラを導入します。 4)クラウドネイティブアプリケーションは、DockerおよびKubernetesを介して展開され、柔軟性とスケーラビリティを向上させます。

PHP対その他の言語:比較PHP対その他の言語:比較Apr 13, 2025 am 12:19 AM

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

PHP対Python:コア機能と機能PHP対Python:コア機能と機能Apr 13, 2025 am 12:16 AM

PHPとPythonにはそれぞれ独自の利点があり、さまざまなシナリオに適しています。 1.PHPはWeb開発に適しており、組み込みのWebサーバーとRich Functionライブラリを提供します。 2。Pythonは、簡潔な構文と強力な標準ライブラリを備えたデータサイエンスと機械学習に適しています。選択するときは、プロジェクトの要件に基づいて決定する必要があります。

PHP:Web開発の重要な言語PHP:Web開発の重要な言語Apr 13, 2025 am 12:08 AM

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

PHP:多くのウェブサイトの基礎PHP:多くのウェブサイトの基礎Apr 13, 2025 am 12:07 AM

PHPが多くのWebサイトよりも優先テクノロジースタックである理由には、その使いやすさ、強力なコミュニティサポート、広範な使用が含まれます。 1)初心者に適した学習と使用が簡単です。 2)巨大な開発者コミュニティと豊富なリソースを持っています。 3)WordPress、Drupal、その他のプラットフォームで広く使用されています。 4)Webサーバーとしっかりと統合して、開発の展開を簡素化します。

誇大広告を超えて:今日のPHPの役割の評価誇大広告を超えて:今日のPHPの役割の評価Apr 12, 2025 am 12:17 AM

PHPは、特にWeb開発の分野で、最新のプログラミングで強力で広く使用されているツールのままです。 1)PHPは使いやすく、データベースとシームレスに統合されており、多くの開発者にとって最初の選択肢です。 2)動的コンテンツ生成とオブジェクト指向プログラミングをサポートし、Webサイトを迅速に作成および保守するのに適しています。 3)PHPのパフォーマンスは、データベースクエリをキャッシュおよび最適化することで改善でき、その広範なコミュニティと豊富なエコシステムにより、今日のテクノロジースタックでは依然として重要になります。

PHPの弱い参照は何ですか、そしていつ有用ですか?PHPの弱い参照は何ですか、そしていつ有用ですか?Apr 12, 2025 am 12:13 AM

PHPでは、弱い参照クラスを通じて弱い参照が実装され、ガベージコレクターがオブジェクトの回収を妨げません。弱い参照は、キャッシュシステムやイベントリスナーなどのシナリオに適しています。オブジェクトの生存を保証することはできず、ごみ収集が遅れる可能性があることに注意する必要があります。

PHPで__invoke Magicメソッドを説明してください。PHPで__invoke Magicメソッドを説明してください。Apr 12, 2025 am 12:07 AM

\ _ \ _ Invokeメソッドを使用すると、オブジェクトを関数のように呼び出すことができます。 1。オブジェクトを呼び出すことができるように\ _ \ _呼び出しメソッドを定義します。 2。$ obj(...)構文を使用すると、PHPは\ _ \ _ Invokeメソッドを実行します。 3。ロギングや計算機、コードの柔軟性の向上、読みやすさなどのシナリオに適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。