我一直在使用 mysqlnd 查看 PHP 中的异步数据库请求。代码工作正常,但比较从一个合理大小的表中提取数据与使用异步请求跨多个表分割相同数据的性能,我没有得到任何像我期望的性能,尽管它看起来确实根据硬件设置相当可改变。
据我了解,我应该实现的目标,而不是:
x = a + b + c + d
相反:
x = max(a, b, c, d)
其中,x
是所花费的总时间,a
到 d
是各个请求的时间。我实际上看到的是某些设置的性能略有提高,而其他设置的性能则较差,就好像请求根本不是异步的一样。欢迎参与此工作并遇到相同问题的其他人提供任何想法或经验。
编辑:在这里测量时间,我们讨论的是分布在 10 个表上的查询,单独的查询花费的时间不超过 8 秒左右即可完成,结合每个单独的请求完成所需的时间(非异步)总共约为 18 秒秒。
异步执行相同的请求总查询时间也约为 18 秒。很明显,请求没有针对数据库并行执行。
编辑:使用的代码与文档 here 中所示完全相同
<?php
$link1 = mysqli_connect();
$link1->query("SELECT 'test'", MYSQLI_ASYNC);
$all_links = array($link1);
$processed = 0;
do {
$links = $errors = $reject = array();
foreach ($all_links as $link) {
$links[] = $errors[] = $reject[] = $link;
}
if (!mysqli_poll($links, $errors, $reject, 1)) {
continue;
}
foreach ($links as $link) {
if ($result = $link->reap_async_query()) {
print_r($result->fetch_row());
if (is_object($result))
mysqli_free_result($result);
} else die(sprintf("MySQLi Error: %s", mysqli_error($link)));
$processed++;
}
} while ($processed < count($all_links));
?>
最佳答案
我将扩展我的评论,并尝试解释为什么使用当前的设置无法获得任何性能。
在您的情况下,异步意味着检索数据的过程与代码的其余部分相比是异步的。两个移动部分(获取数据)和处理数据是分开的,并且依次执行,但仅在数据到达时执行。
这意味着您希望充分利用 CPU,因此在数据准备好之前不会调用 PHP 代码。
为了实现这一点,您必须夺取 PHP 进程的控制权并使其使用操作系统的事件接口(interface)之一(Linux 上的 epoll
或 Linux 上的 IOCP
window )。由于 PHP 要么嵌入到 Web 服务器 (mod_php
) 中,要么作为其自己的独立 FCGI 服务器 (php-fpm
) 运行,这意味着异步数据获取的最佳利用将是当您运行 CLI php 脚本时,因为否则很难利用事件接口(interface)。
但是,让我们关注您的问题以及为什么您的代码速度不快。
您假设您受到 CPU 限制,并且您的解决方案是以 block 的形式检索数据并以这种方式处理它们 - 这很好,但是由于您所做的任何事情都不会产生更快的执行速度,这意味着您受到 100% I/O 限制。
从数据库检索数据的过程会强制硬盘执行查找。不管你“分块”多少,如果磁盘很慢并且数据分散在磁盘上,那部分就会很慢,并且创建更多的工作人员来处理部分数据只会使系统变得越来越慢,因为每个工作人员在检索数据时都会遇到相同的问题。
我的结论是,您的问题在于硬盘速度慢,数据集太大,可能无法正确构建分块检索。我建议更新此问题或创建另一个问题,以帮助您更快、更优化地检索数据。
关于php - MySQL异步数据库请求性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32139584/