Connection open + one select + close takes about 30 ms
mvorisek opened this issue · comments
I am debugging a php-src 9151 issue and I decided to use this library to check if the issue is present with pure PHP MySQL impl. too or not.
My code looks like:
foreach (range(0, 10_000) as $i) {
$pdo = null;
try {
$res = null;
\Amp\Loop::run(function () use ($dbHost, $dbUser, $dbPassword, $dbDatabase, &$res) {
$db = \Amp\Mysql\pool(\Amp\Mysql\ConnectionConfig::fromString(
'host=' . $dbHost . ';user=' . $dbUser . ';pass=' . $dbPassword . ';db=' . $dbDatabase
));
/** @var \Amp\Mysql\ResultSet $result */
$result = yield $db->query('SELECT \'test\' as v');
$res = [];
while (yield $result->advance()) {
$res[] = $result->getCurrent();
}
$db->close();
});
$this->assertSame([['v' => 'test']], $res);
} catch (\Exception $e) {
throw new \Exception('Failed after ' . $i . ' iterations', 0, $e);
}
}
But it executes more than 10x slower than similar open connection + one select query + close connection code with native \PDO
driver.
With amp/mysql
the time per iteration is about 30 ms. But I would expect no more than 5 ms / iter. in average.
My question is, why is amp/mysql
so slow and can I improve the code above somehow?
Please note, it is intentional to close and reopen the connection in each iteration for my test usecase.
Please try opening a single connection instead of creating a new pool and closing it each time. I expect it to be a bit slower, but we should investigate what makes it that much slower.
FYI, without a pool ($db = yield \Amp\Mysql\connect(\Amp\Mysql\ConnectionConfig::fromString(...));
) it is a little faster, but still very slow. I run is several times and I cannot get under 20s / 1000 iters.
I think this is probably mainly caused by PDO using the old mysql_native_password
, while amphp/mysql
supports the newer caching_sha2_password
pluggable authentication. caching_sha2_password
however, comes with quite some cost, because the client needs to fetch the server's public key and computed openssl_public_encrypt
(which takes about 13% in my benchmark).
@mvorisek Turns out there was a bug in the caching_sha2_password
implementation, which made it always to a full authentication roundtrip instead of using the fast auth flow.
I'm at 3s for 1000 iterations now instead of 7s with a local mysql docker container.
@kelunik nice finding, thank you ❤️