简体   繁体   English

PHP Amp\Mysql 异步比原生阻塞 PDO 慢?

[英]PHP Amp\Mysql async slower than native blocking PDO?

I'm doing some testing with Amp and try to see how it could help speeding up SQL Queries by running them async.我正在使用Amp进行一些测试,并尝试通过异步运行 SQL 查询来帮助加速它们。 I think I'm doing something wrong because the results of this test file are very disappointing and not what I would have expected.我认为我做错了什么,因为这个测试文件的结果非常令人失望,而不是我所期望的。 Is there something I'm doing wrong?有什么我做错了吗?

The code below gives me results like this, first number is Amp\Mysql and it is a lot slower for some reason:下面的代码给了我这样的结果,第一个数字是 Amp\Mysql 并且由于某种原因它要很多:

0.37159991264343
0.10906314849854

PHP code: PHP 代码:

<?php
require 'vendor/autoload.php';
require 'Timer.php';

$runThisManyTimes = 1000;

///////////////////////////////////////////////////////////

use Amp\Mysql\ConnectionConfig;
use Amp\Loop;

Loop::run(function() use ($runThisManyTimes) {
    $timer = Timer::start();

    $config = ConnectionConfig::fromString(
        "host=127.0.0.1 user=test password=test db=test "
    );

    /** @var \Amp\Mysql\Pool $pool */
    $pool = Amp\Mysql\pool($config);

    /** @var \Amp\Mysql\Statement $statement */
    $statement = yield $pool->prepare("SELECT * FROM accounts WHERE id = :id");

    for ($i = 1; $i <= $runThisManyTimes; $i++) {
        /** @var \Amp\Mysql\ResultSet $result */
        $result = yield $statement->execute(['id' => '206e5903-98bd-4af5-8fb1-86a520e9a330']);

        while (yield $result->advance()) {
            $row = $result->getCurrent();

        }
    }

    $timer->stop();
    echo $timer->getSeconds();

    Loop::stop();
});

echo PHP_EOL;

///////////////////////////////////////////////////////////

$timer = Timer::start();

$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'test', 'test');

$statement = $pdo->prepare("SELECT * FROM accounts WHERE id = :id");

for ($i = 1; $i <= $runThisManyTimes; $i++) {
    $statement->execute(['id' => '206e5903-98bd-4af5-8fb1-86a520e9a330']);
    $statement->fetch();
}

$timer->stop();
echo $timer->getSeconds();

Parallel execution of MySQL is not productive when each thread takes less than, say, 1 second.当每个线程花费的时间少于 1 秒时,MySQL 的并行执行是无效的。

Each thread must use its own connection;每个线程必须使用自己的连接; establishing the connection takes some time.建立连接需要一些时间。

Your particular benchmark (like most benchmarks) is not very useful.您的特定基准(如大多数基准)不是很有用。 After the first execution of that single SELECT , all subsequent executions will probably take less than 1ms.在第一次执行该单个SELECT ,所有后续执行可能需要不到 1 毫秒。 It would be better to use a sequence of statements that reflect your app.最好使用反映您的应用程序的一系列语句。

Your benchmark doesn't include any concurrency, so it's basically like blocking I/O in the PDO example.您的基准测试不包括任何并发性,因此它基本上就像 PDO 示例中的阻塞 I/O。 amphp/mysql is a full protocol implementation in PHP, so it's somewhat expected to be slower than the C implementation of PDO. amphp/mysql是 PHP 中的完整协议实现,因此预计它会比 PDO 的 C 实现慢。

If you want to find out whether non-blocking concurrent I/O has benefits for your application and you're currently using sequential blocking PDO queries, you should benchmark those against non-blocking concurrent queries using amphp/mysql instead of serial ones.如果您想了解非阻塞并发 I/O 是否对您的应用程序有好处,并且您当前正在使用顺序阻塞 PDO 查询,您应该使用amphp/mysql而不是串行查询,对非阻塞并发查询进行基准测试。

Additionally, amphp/mysql might not be optimized as much as the database drivers behind PDO, but it allows for non-blocking concurrent queries, which isn't supported by PDO.此外, amphp/mysql的优化可能不如 PDO 背后的数据库驱动程序那么优化,但它允许非阻塞并发查询,这是 PDO 不支持的。 If you do sequential queries, PDO will definitely have better performance for the time being, but amphp/mysql is very useful once concurrency is involved.如果做顺序查询的话,PDO暂时肯定会有更好的性能,但是一旦涉及到并发, amphp/mysql就非常有用了。

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

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