MySQL非同期クエリ

mysqlndでは、MySQLへのクエリを非同期で実行できるようになりました。つまり、クエリが完了するのを待たずにスクリプトを続行し、結果を生成できるようになりました。 このアプローチの利点は明らかです。なぜなら、リクエストを待っている間に多くの有用な作業を行うことができるからです。しかし、最初に少し異なる例を示します。



3つのクエリ( q1q2q3 )があり、各クエリが特定の時間( t1t2t3 )実行されると仮定します。たとえば、次のようになります。



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: バグは公開されており、クイックフィックスはすでに存在しています



All Articles