3つのクエリ( q1 、 q2 、 q3 )があり、各クエリが特定の時間( t1 、 t2 、 t3 )実行されると仮定します。たとえば、次のようになります。
SELECT 1 AS val, SLEEP(1) AS sleep SELECT 2 AS val, SLEEP(2) AS sleep SELECT 3 AS val, SLEEP(3) AS sleep
同期クエリ実行の場合、 t1 + t2 + t3 (例:6秒)で実行結果を取得できます。 非同期クエリ実行の場合は、既に最大(t1、t2、t3) (例:3秒)
非同期クエリの使用例、およびmysqlndの使用例は、 githubにあります。
非同期リクエストの実行
非同期クエリを実行するには、特別なMYSQLI_ASYNCフラグを指定するだけです。
mysqli_query($link, $query, MYSQLI_ASYNC);
この定数は拡張機能で直接宣言されているため、上記の式はmysqlndなしでは実行されません。 クエリを同期的に実行する機能を提供するために、mysqlndがない場合、クエリを実行するためのいくつかのオプションがあります。
// ( notice - !) mysqli_query($link, $query, MYSQLI_ASYNC || MYSQLI_USE_RESULT); // $flag = defined('MYSQLI_ASYNC') ? MYSQLI_ASYNC : MYSQLI_USE_RESULT; mysqli_query($link, $query, $flag); // defined('MYSQLI_ASYNC') || define('MYSQLI_ASYNC', MYSQLI_USE_RESULT); mysqli_query($link, $query, MYSQLI_ASYNC);
この関数の通常の結果とは異なり、非同期読み取り要求(SELECTなど)の場合、mysqli_resultではなくtrueを返します。
非同期リクエストの検証
mysqli_poll関数は、非同期リクエストの実行を確認するために使用されます。 残念ながら、関数は文書化されておらず、パラメーターのセットは困惑しています。そのため、ソースに移動して何が起こるかを確認する必要がありました。 その結果、この関数は、 stream_select関数のように、 selectシステムコールのラッパーであることがわかりました 。
確認する必要があるmysqliオブジェクトと検証タイムアウトの値(sec、[usec])を含む3つの配列がmysqli_poll関数入力に提供されます。 配列は対応するファイル記述子のセットに変換され、タイムアウト値はtimeval構造に変換され、selectシステムコールへの入力に渡されます。その後、記述子はmysqliオブジェクトに変換され、selectシステムコールの結果が返されます。 非同期リクエストの結果を確認する例は、 ここにあります 。
クエリ結果の取得
非同期クエリの結果を取得するには、 mysqli_reap_async_query関数を使用します。 関数呼び出しは常に要求からロックを削除するため、この呼び出しがなければ、後続のすべての要求は「コマンドが同期していません」から落ちます。読み取り要求(SELECTなど)の場合、関数はmysqli_resultを返します。 »データベースの操作を続行するには、残りはboolです。
ユースケース
非同期要求を使用する主な利点は、CPU時間をより効率的に使用できることです。 記事の冒頭に、多くの非同期データベースクエリ( コード )を実行できる速さを示す例があります。 さらに、開発者は多くの場合、データベースへの移行を書き込むタスクに直面します。 移行は通常、スキーマ移行(CREATE、ALTER、DROP)とデータ移行(INSERT、UPDATE、DELETE)に分けられます。 大きなテーブルを操作する場合、ALTERの実行には長い時間がかかります。これは、UPDATE( code )のデータを準備するために効果的に使用できます。
PS非同期リクエストの処理はまだ完全には透過的ではないため、次のようにお願いします。
1. mysqli_pollを介して受信エラー(エラー配列内のmysqliオブジェクトの外観)をシミュレートできませんでした。 これを行う方法がわかっている場合は、plzを作成し、必ず記事に追加してください。
2. mysqli_pollを呼び出す前に接続を閉じると、segfaultが発生します(ubuntu 12.04、php 5.3.10)。 Plzは次のコードを自分で再現します。バグを報告する必要があるかもしれません。
$link = new mysqli('host', 'user', 'password', 'db', 'port'); mysqli_close($link); $read = $error = $reject = array(); $read[] = $error[] = $reject[] = $link; mysqli_poll($read, $error, $reject, 1);
UPD: バグは公開されており、クイックフィックスはすでに存在しています