简体   繁体   English

为什么PHP Mysql multi_query()比循环query()慢

[英]Why PHP Mysql multi_query() is slower than loop query()

I'm working on HHVM with MySQL. 我正在使用MySQL开发HHVM。 And I'm really confused to find out that batching 2000 sql queries using multi_query() is much slower than a 2000 loop with single query() (please see the code and the result at end). 我真的很困惑,发现使用multi_query()批处理2000 sql查询要比使用单个query()的2000循环慢得多(请查看代码和最后的结果)。 By further profiling, I found the API next_result() takes most of the time (~70%). 通过进一步剖析,我发现API next_result()花费了大部分时间(〜70%)。

My questions are: 我的问题是:
(1) Why the API next_result() is so slow? (1)为什么API next_result()这么慢?
(2) If I want to do thousands of sql queries together, is there any way better than a naive loop? (2)如果我想一起执行数千个sql查询,还有什么比天真的循环更好的方法吗?
Thanks! 谢谢!

Here is the code (php): 这是代码(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";

The result is following: 结果如下:

Single query: 526.38602256775 ms
Multi query: 1408.7419509888 ms

Note: next_result() will consume 922ms in this case. 注意:在这种情况下,next_result()将消耗922ms。

The simplest answer here is overhead. 这里最简单的答案是开销。 multi_query() builds a data object for each result set. multi_query()为每个结果集构建一个数据对象。 It then has to store that object over and over. 然后,它必须反复存储该对象。

By contrast, you're running the same query over and over but only writing a simple data array to store the results. 相比之下,您一次又一次地运行相同的查询,但只编写了一个简单的数据数组来存储结果。 PHP can then free the memory of the previous result set because you're constantly overwriting the same variable (once a data object has nothing pointing to it internally it can be garbage collected ). 然后,PHP可以释放先前结果集的内存,因为您一直在覆盖同一变量(一旦数据对象内部没有指向它的数据,就可以对其进行垃圾回收 )。

This isn't a very good use case, though. 但是,这不是一个很好的用例。 There's no real world application here because there's no need to run the same query over and over (your DB should cache the results the first run and then store the data in memory to faster retrieval). 这里没有现实世界的应用程序,因为不需要一遍又一遍地运行相同的查询(您的数据库应在第一次运行时缓存结果,然后将数据存储在内存中以加快检索速度)。 For a single result set , the difference here is negligible. 对于单个结果集 ,此处的差异可以忽略不计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM