0

私はMySQLでHHVMに取り組んでいます。そして、multi_query() を使用して 2000 個の SQL クエリをバッチ処理すると、単一の query() を使用した 2000 個のループよりもはるかに遅いことがわかり、本当に混乱しています (最後にコードと結果を参照してください)。さらにプロファイリングすると、API next_result() がほとんどの時間 (~70%) を占めていることがわかりました。

私の質問は次のとおりです:
(1) API next_result() が非常に遅いのはなぜですか?
(2) 何千もの SQL クエリを一緒に実行したい場合、単純なループよりも優れた方法はありますか?
ありがとう!

コード(php)は次のとおりです。

$conn = new mysqli("localhost", "root", "pwd", "table");

$loop = 2000;
$q = "select * from ContactInfo;";

// single query in a loop
$results = array();
$sq_start = microtime(true);
for ($i=0; $i < $loop; $i++) {
  $ret = $conn->query($q);
  $results[] = $ret;
}
for ($i=0; $i < $loop; $i++) {
  $xx = $results[$i]->fetch_all();
}
$sq_end = microtime(true);

// construct the multi-query
for ($i=0; $i < $loop; $i++) {
  $m_q .= $q; 
}

// multi-query in one round-trip
$mq_start = microtime(true);
$conn->multi_query($m_q);
do {
  $ret = $conn->store_result();
  $xx = $ret->fetch_all();
} while($conn->next_result());
$mq_end = microtime(true);

echo "Single query: " . ($sq_end - $sq_start)*1000 . " ms\n";
echo "Multi query: " . ($mq_end - $mq_start)*1000 . " ms\n";

結果は次のとおりです。

Single query: 526.38602256775 ms
Multi query: 1408.7419509888 ms

注: この場合、next_result() は 922 ミリ秒を消費します。

4

1 に答える 1

0

ここでの最も簡単な答えはオーバーヘッドです。multi_query()結果セットごとにデータ オブジェクトを作成します。次に、そのオブジェクトを何度も保存する必要があります。

対照的に、同じクエリを何度も実行していますが、結果を格納するために単純なデータ配列を作成しているだけです。PHP は、同じ変数を常に上書きしているため、前の結果セットのメモリを解放できます (データ オブジェクトが内部的にそれを指しているものがなくなると、ガベージ コレクトされる可能性があります)。

ただし、これはあまり良い使用例ではありません。同じクエリを何度も実行する必要がないため、ここには実際のアプリケーションはありません (DB は最初の実行で結果をキャッシュし、データをメモリに保存して高速に取得する必要があります)。単一の結果セットの場合、ここでの違いはごくわずかです。

于 2016-02-21T02:47:00.963 に答える