Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection open + one select + close takes about 30 ms #118

Closed
mvorisek opened this issue Jul 26, 2022 · 5 comments
Closed

Connection open + one select + close takes about 30 ms #118

mvorisek opened this issue Jul 26, 2022 · 5 comments
Assignees
Labels

Comments

@mvorisek
Copy link

mvorisek commented Jul 26, 2022

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.

@kelunik
Copy link
Member

kelunik commented Jul 26, 2022

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.

@mvorisek
Copy link
Author

mvorisek commented Jul 26, 2022

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.

@kelunik
Copy link
Member

kelunik commented Jul 27, 2022

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).

@kelunik kelunik self-assigned this Sep 25, 2022
@kelunik kelunik added the bug label Sep 25, 2022
@kelunik
Copy link
Member

kelunik commented Sep 25, 2022

@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.

@mvorisek
Copy link
Author

@kelunik nice finding, thank you ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants