|
@@ -21,14 +21,14 @@ class Operation
|
|
public static function fortunes(PDOStatement|PDOStatementProxy $fortune): string
|
|
public static function fortunes(PDOStatement|PDOStatementProxy $fortune): string
|
|
{
|
|
{
|
|
$fortune->execute();
|
|
$fortune->execute();
|
|
- $results = $fortune->fetchAll(PDO::FETCH_KEY_PAIR);
|
|
|
|
|
|
+ $results = $fortune->fetchAll(PDO::FETCH_KEY_PAIR);
|
|
$results[0] = 'Additional fortune added at request time.';
|
|
$results[0] = 'Additional fortune added at request time.';
|
|
asort($results);
|
|
asort($results);
|
|
|
|
|
|
$html = '';
|
|
$html = '';
|
|
foreach ($results as $id => $message) {
|
|
foreach ($results as $id => $message) {
|
|
$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
|
|
$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
|
|
- $html .= "<tr><td>$id</td><td>$message</td></tr>";
|
|
|
|
|
|
+ $html .= "<tr><td>$id</td><td>$message</td></tr>";
|
|
}
|
|
}
|
|
|
|
|
|
return "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>";
|
|
return "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>";
|
|
@@ -36,13 +36,8 @@ class Operation
|
|
|
|
|
|
public static function query(PDOStatement|PDOStatementProxy $query, int $queries): string
|
|
public static function query(PDOStatement|PDOStatementProxy $query, int $queries): string
|
|
{
|
|
{
|
|
- $query_count = 1;
|
|
|
|
- if ($queries > 1) {
|
|
|
|
- $query_count = min($queries, 500);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
$results = [];
|
|
$results = [];
|
|
- while ($query_count--) {
|
|
|
|
|
|
+ while ($queries--) {
|
|
$query->execute([mt_rand(1, 10000)]);
|
|
$query->execute([mt_rand(1, 10000)]);
|
|
$results[] = $query->fetch(PDO::FETCH_ASSOC);
|
|
$results[] = $query->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
}
|
|
@@ -50,33 +45,38 @@ class Operation
|
|
return json_encode($results, JSON_NUMERIC_CHECK);
|
|
return json_encode($results, JSON_NUMERIC_CHECK);
|
|
}
|
|
}
|
|
|
|
|
|
- public static function updates(PDOStatement|PDOStatementProxy $random, PDOStatement|PDOStatementProxy $update, int $queries): string
|
|
|
|
|
|
+ public static function updates(PDOStatement|PDOStatementProxy $random, PDOStatement|PDOStatementProxy $update, int $queries, string $driver): string
|
|
{
|
|
{
|
|
- $query_count = 1;
|
|
|
|
- if ($queries > 1) {
|
|
|
|
- $query_count = min($queries, 500);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- $results = [];
|
|
|
|
- while ($query_count--) {
|
|
|
|
- $id = mt_rand(1, 10000);
|
|
|
|
- $random->execute([$id]);
|
|
|
|
- $item = $random->fetch(PDO::FETCH_ASSOC);
|
|
|
|
- $update->execute([$item['randomNumber'] = mt_rand(1, 10000), $id]);
|
|
|
|
|
|
+ $results = $keys = $values = [];
|
|
|
|
+ while ($queries--) {
|
|
|
|
+ $random->execute([mt_rand(1, 10000)]);
|
|
|
|
+ $item = $random->fetch(PDO::FETCH_ASSOC);
|
|
|
|
+ $item['randomNumber'] = mt_rand(1, 10000);
|
|
|
|
+ $results[] = $item;
|
|
|
|
|
|
- $results[] = $item;
|
|
|
|
|
|
+ if ($driver == 'pgsql') {
|
|
|
|
+ $values[] = $keys[] = $item['id'];
|
|
|
|
+ $values[] = $item['randomNumber'];
|
|
|
|
+ } else {
|
|
|
|
+ $update->execute([$item['randomNumber'], $item['id']]);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if ($driver == 'pgsql') {
|
|
|
|
+ $update->execute([...$values, ...$keys]);
|
|
|
|
+ }
|
|
return json_encode($results, JSON_NUMERIC_CHECK);
|
|
return json_encode($results, JSON_NUMERIC_CHECK);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class Connection
|
|
class Connection
|
|
{
|
|
{
|
|
|
|
+ private static PDO $pdo;
|
|
|
|
+ private static string $driver;
|
|
|
|
+ private static array $updates = [];
|
|
private static PDOStatement $db;
|
|
private static PDOStatement $db;
|
|
private static PDOStatement $fortune;
|
|
private static PDOStatement $fortune;
|
|
private static PDOStatement $random;
|
|
private static PDOStatement $random;
|
|
- private static PDOStatement $update;
|
|
|
|
private static PDOStatement $query;
|
|
private static PDOStatement $query;
|
|
|
|
|
|
public static function init(string $driver): void
|
|
public static function init(string $driver): void
|
|
@@ -87,15 +87,16 @@ class Connection
|
|
"benchmarkdbpass",
|
|
"benchmarkdbpass",
|
|
[
|
|
[
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
|
|
- PDO::ATTR_EMULATE_PREPARES => false
|
|
|
|
|
|
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
|
|
+ PDO::ATTR_EMULATE_PREPARES => false
|
|
]
|
|
]
|
|
);
|
|
);
|
|
|
|
|
|
- self::$db = self::$random = self::$query = $pdo->prepare(Operation::WORLD_SELECT_SQL);
|
|
|
|
|
|
+ self::$db = self::$random = self::$query = $pdo->prepare(Operation::WORLD_SELECT_SQL);
|
|
self::$fortune = $pdo->prepare(Operation::FORTUNE_SQL);
|
|
self::$fortune = $pdo->prepare(Operation::FORTUNE_SQL);
|
|
- self::$update = $pdo->prepare(Operation::WORLD_UPDATE_SQL);
|
|
|
|
|
|
|
|
|
|
+ self::$pdo = $pdo;
|
|
|
|
+ self::$driver = $driver;
|
|
}
|
|
}
|
|
|
|
|
|
public static function db(): string
|
|
public static function db(): string
|
|
@@ -115,13 +116,23 @@ class Connection
|
|
|
|
|
|
public static function updates(int $queries): string
|
|
public static function updates(int $queries): string
|
|
{
|
|
{
|
|
- return Operation::updates(self::$random, self::$update, $queries);
|
|
|
|
|
|
+ if (!isset(self::$updates[$queries])) {
|
|
|
|
+ self::$updates[$queries] = self::$driver == 'pgsql'
|
|
|
|
+ ? self::$pdo->prepare('UPDATE World SET randomNumber = CASE id'.\str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $queries).'END WHERE id IN ('.\str_repeat('?::INTEGER,', $queries - 1).'?::INTEGER)')
|
|
|
|
+ : self::$pdo->prepare(Operation::WORLD_UPDATE_SQL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return Operation::updates(self::$random, self::$updates[$queries], $queries, self::$driver);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class Connections
|
|
class Connections
|
|
{
|
|
{
|
|
private static PDOPool $pool;
|
|
private static PDOPool $pool;
|
|
|
|
+ private static string $driver;
|
|
|
|
+ private static array $dbs = [];
|
|
|
|
+ private static array $fortunes = [];
|
|
|
|
+ private static array $updates = [];
|
|
|
|
|
|
public static function init(string $driver): void
|
|
public static function init(string $driver): void
|
|
{
|
|
{
|
|
@@ -133,22 +144,22 @@ class Connections
|
|
->withUsername('benchmarkdbuser')
|
|
->withUsername('benchmarkdbuser')
|
|
->withPassword('benchmarkdbpass');
|
|
->withPassword('benchmarkdbpass');
|
|
|
|
|
|
- self::$pool = new PDOPool($config, intval(1024 / swoole_cpu_num()));
|
|
|
|
|
|
+ self::$pool = new PDOPool($config, 128);
|
|
|
|
+ self::$driver = $driver;
|
|
}
|
|
}
|
|
|
|
|
|
public static function db(): string
|
|
public static function db(): string
|
|
{
|
|
{
|
|
- $pdo = self::get();
|
|
|
|
- $result = Operation::db($pdo->prepare(Operation::WORLD_SELECT_SQL));
|
|
|
|
|
|
+ $pdo = self::get();
|
|
|
|
+ $result = Operation::db(self::getStatement($pdo, 'select'));
|
|
self::put($pdo);
|
|
self::put($pdo);
|
|
-
|
|
|
|
return $result;
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
|
|
public static function fortunes(): string
|
|
public static function fortunes(): string
|
|
{
|
|
{
|
|
- $pdo = self::get();
|
|
|
|
- $result = Operation::fortunes($pdo->prepare(Operation::FORTUNE_SQL));
|
|
|
|
|
|
+ $pdo = self::get();
|
|
|
|
+ $result = Operation::fortunes(self::getStatement($pdo, 'fortunes'));
|
|
self::put($pdo);
|
|
self::put($pdo);
|
|
|
|
|
|
return $result;
|
|
return $result;
|
|
@@ -156,8 +167,8 @@ class Connections
|
|
|
|
|
|
public static function query(int $queries): string
|
|
public static function query(int $queries): string
|
|
{
|
|
{
|
|
- $pdo = self::get();
|
|
|
|
- $result = Operation::query($pdo->prepare(Operation::WORLD_SELECT_SQL), $queries);
|
|
|
|
|
|
+ $pdo = self::get();
|
|
|
|
+ $result = Operation::query(self::getStatement($pdo, 'select'), $queries);
|
|
self::put($pdo);
|
|
self::put($pdo);
|
|
|
|
|
|
return $result;
|
|
return $result;
|
|
@@ -165,8 +176,8 @@ class Connections
|
|
|
|
|
|
public static function updates(int $queries): string
|
|
public static function updates(int $queries): string
|
|
{
|
|
{
|
|
- $pdo = self::get();
|
|
|
|
- $result = Operation::updates($pdo->prepare(Operation::WORLD_SELECT_SQL), $pdo->prepare(Operation::WORLD_UPDATE_SQL), $queries);
|
|
|
|
|
|
+ $pdo = self::get();
|
|
|
|
+ $result = Operation::updates(self::getStatement($pdo, 'select'), self::getStatement($pdo, 'update', $queries), $queries, self::$driver);
|
|
self::put($pdo);
|
|
self::put($pdo);
|
|
|
|
|
|
return $result;
|
|
return $result;
|
|
@@ -181,4 +192,31 @@ class Connections
|
|
{
|
|
{
|
|
self::$pool->put($db);
|
|
self::$pool->put($db);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private static function getStatement(PDO|PDOProxy $pdo, string $type, int $queries = 0): PDOStatement|PDOStatementProxy
|
|
|
|
+ {
|
|
|
|
+ $hash = spl_object_id($pdo);
|
|
|
|
+
|
|
|
|
+ if ('select' == $type) {
|
|
|
|
+ if (!isset(self::$dbs[$hash])) {
|
|
|
|
+ self::$dbs[$hash] = $pdo->prepare(Operation::WORLD_SELECT_SQL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return self::$dbs[$hash];
|
|
|
|
+ } elseif ('fortunes' == $type) {
|
|
|
|
+ if (!isset(self::$fortunes[$hash])) {
|
|
|
|
+ self::$fortunes[$hash] = $pdo->prepare(Operation::FORTUNE_SQL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return self::$fortunes[$hash];
|
|
|
|
+ } else {
|
|
|
|
+ if (!isset(self::$updates[$hash][$queries])) {
|
|
|
|
+ self::$updates[$hash][$queries] = self::$driver == 'pgsql'
|
|
|
|
+ ? $pdo->prepare('UPDATE World SET randomNumber = CASE id'.\str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $queries).'END WHERE id IN ('.\str_repeat('?::INTEGER,', $queries - 1).'?::INTEGER)')
|
|
|
|
+ : $pdo->prepare(Operation::WORLD_UPDATE_SQL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return self::$updates[$hash][$queries];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|