3v4l.org

run code in 300+ PHP versions simultaneously
<?php /*---------------------------------------------------------------------- ユニークキーの値が既存ならIDを取得し, なければ保存してからIDを取得 という処理において早い方法はなにか? 以下メソッドを比較してテスト bulkInsertAndIfDuplicateGetIds1() bulkInsertAndIfDuplicateGetIds2() bulkInsertAndIfDuplicateGetIds3() ----------------------------------------------------------------------*/ $testUser = new TestUser(); // 挿入データ // initRows() でINSERTされるデータに対し2番目だけが新規なので // 挿入を試みると ["1","5","3"] が返ることを期待するが, 結果は下記 echo の通り $users = [ ['name' => 'John', 'kind' => 'TypeA', 'age' => 25], // 既存 ['name' => 'Bob', 'kind' => 'TypeC', 'age' => 22], // 新規 ['name' => 'Alice', 'kind' => 'TypeB', 'age' => 30], // 既存 ]; // 挿入実行 $testUser->initRows(); $result1 = $testUser->bulkInsertAndIfDuplicateGetIds1($users); $testUser->initRows(); $result2 = $testUser->bulkInsertAndIfDuplicateGetIds2($users); $testUser->initRows(); $result3 = $testUser->bulkInsertAndIfDuplicateGetIds3($users); // 結果確認 echo '<p>result1</p>' . json_encode($result1); // ["1","5","3"] echo '<p>result2</p>' . json_encode($result2); // ["4","4","4"] echo '<p>result3</p>' . json_encode($result3); // ["4","4","4"] // テストユーザークラス final class TestUser { private \PDO $pdo; public function __construct() { $host = 'localhost'; $dbname = 'database_name'; $user = 'username'; $password = 'password'; $dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4"; $this->pdo = new PDO($dsn, $user, $password); } // 初期状態として3レコード入れておく final public function initRows(): void { try { // テーブル作成 $this->pdo->query(" CREATE TABLE IF NOT EXISTS test_users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), kind VARCHAR(255), age INT, UNIQUE KEY unique_name_kind (name, kind) ) "); // レコード削除 $this->pdo->query(" TRUNCATE TABLE test_users; ALTER TABLE test_users AUTO_INCREMENT = 1; "); // 3レコード入れておく $this->pdo->query(" INSERT INTO test_users (name, kind, age) VALUES ('John', 'TypeA', 25), ('John', 'TypeB', 30), ('Alice', 'TypeB', 28) "); } catch (\PDOException $e) { echo $e->getMessage(); } } // 方法1 // execute() を複数回 // ON DUPLICATE KEY UPDATE は LAST_INSERT_ID を指定 final public function bulkInsertAndIfDuplicateGetIds1(array $users): array { // 返り値のID配列 $ids = []; // INSERT文 $sql = 'INSERT INTO test_users (name, kind, age) VALUES (:name, :kind, :age) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id)'; try { $stmt = $this->pdo->prepare($sql); foreach ($users as $user) { $stmt->execute($user); $ids[] = $this->pdo->lastInsertId(); } return $ids; } catch (\PDOException $e) { echo $e->getMessage(); } } // 方法2 // execute() を1回 // ON DUPLICATE KEY UPDATE は LAST_INSERT_ID を指定 final public function bulkInsertAndIfDuplicateGetIds2(array $users): array { // 返り値のID配列 $ids = []; // INSERT文 $placeholders = implode(', ', array_fill(0, count($users), '(?, ?, ?)')); $sql = 'INSERT INTO test_users (name, kind, age) VALUES ' . $placeholders . ' ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id)'; try { $stmt = $this->pdo->prepare($sql); $params = []; foreach ($users as $user) { $params = array_merge($params, array_values($user)); } $stmt->execute($params); for ($i = 0; $i < count($users); $i++) { $ids[] = $this->pdo->lastInsertId(); } return $ids; } catch (\PDOException $e) { echo $e->getMessage(); } } // 方法3 // execute() を1回 // ON DUPLICATE KEY UPDATE は ユニークキーを指定 final public function bulkInsertAndIfDuplicateGetIds3(array $users): array { // 返り値のID配列 $ids = []; // INSERT文 $placeholders = implode(', ', array_fill(0, count($users), '(?, ?, ?)')); $sql = 'INSERT INTO test_users (name, kind, age) VALUES ' . $placeholders . ' ON DUPLICATE KEY UPDATE name = VALUES(name), kind = VALUES(kind)'; try { $stmt = $this->pdo->prepare($sql); $params = []; foreach ($users as $user) { $params = array_merge($params, array_values($user)); } $stmt->execute($params); for ($i = 0; $i < count($users); $i++) { $ids[] = $this->pdo->lastInsertId(); } return $ids; } catch (\PDOException $e) { echo $e->getMessage(); } } }

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.4.120.0070.00219.48
8.4.110.0140.00722.61
8.4.100.0140.00717.84
8.4.90.0090.00920.44
8.4.80.0110.00718.75
8.4.70.0130.00818.90
8.4.60.0130.00720.29
8.4.50.0110.00719.72
8.4.40.0030.00617.93
8.4.30.0150.00618.96
8.4.20.0190.00020.82
8.4.10.0100.01019.63
8.3.250.0130.00618.80
8.3.240.0070.01116.78
8.3.230.0030.00516.54
8.3.220.0140.00419.13
8.3.210.0090.00718.38
8.3.200.0070.00216.54
8.3.190.0130.00616.78
8.3.180.0140.00516.55
8.3.170.0120.00818.93
8.3.160.0120.00617.32
8.3.150.0100.01017.16
8.3.140.0070.00716.68
8.3.130.0030.00618.39
8.3.120.0090.00620.80
8.3.110.0030.00620.94
8.3.100.0000.00916.88
8.3.90.0030.00516.41
8.3.80.0060.00318.43
8.3.70.0000.01616.74
8.3.60.0130.01018.31
8.3.50.0070.01116.73
8.3.40.0070.00720.23
8.3.30.0110.00421.94
8.3.20.0050.00324.18
8.3.10.0000.00824.66
8.3.00.0040.00426.16
8.2.290.0090.01116.66
8.2.280.0030.00520.40
8.2.270.0150.00317.25
8.2.260.0090.00916.74
8.2.250.0080.00018.54
8.2.240.0040.00418.84
8.2.230.0070.00322.58
8.2.220.0000.00824.06
8.2.210.0140.00426.77
8.2.200.0080.00418.41
8.2.190.0090.00616.63
8.2.180.0100.01018.21
8.2.170.0090.00919.21
8.2.160.0140.00022.96
8.2.150.0000.00825.66
8.2.140.0040.00424.66
8.2.130.0040.00426.16
8.2.120.0040.00419.77
8.2.110.0120.00922.27
8.2.100.0190.00620.93
8.2.90.0240.01218.96
8.2.80.0230.00318.93
8.2.70.0260.00618.75
8.2.60.0220.00618.81
8.2.50.0190.00420.06
8.2.40.0180.00418.78
8.2.30.0170.01018.68
8.2.20.0140.00319.12
8.2.10.0120.00318.92
8.2.00.0070.00719.21
8.1.330.0080.01016.18
8.1.320.0080.01118.18
8.1.310.0040.00416.66
8.1.300.0120.00420.29
8.1.290.0090.00318.88
8.1.280.0150.00325.92
8.1.270.0050.00524.66
8.1.260.0000.00826.35
8.1.250.0140.00428.09
8.1.240.0130.00018.58
8.1.230.0150.00018.49
8.1.220.0090.00618.63
8.1.210.0100.00319.73
8.1.200.0050.00918.54
8.1.190.0150.00018.42
8.1.180.0120.00318.42
8.1.170.0030.01018.66
8.1.160.0110.00318.85
8.1.150.0040.00820.44
8.1.140.0050.00818.56
8.1.130.0110.00418.61
8.1.120.0000.01218.50
8.1.110.0090.00319.62
8.1.100.0050.00918.55
8.1.90.0070.00718.62
8.1.80.0250.00018.50
8.1.70.0160.00318.62
8.1.60.0150.00018.86
8.1.50.0130.00318.50
8.1.40.0090.00618.73
8.1.30.0080.00518.92
8.1.20.0070.01018.76
8.1.10.0070.00718.79
8.1.00.0100.00518.87
8.0.300.0110.00417.94
8.0.290.0120.00418.06
8.0.280.0070.00717.93
8.0.270.0090.00617.90
8.0.260.0070.00418.44
8.0.250.0150.00017.83
8.0.240.0000.01418.09
8.0.230.0120.00018.28
8.0.220.0150.00017.96
8.0.210.0100.00318.07
8.0.200.0120.00317.99
8.0.190.0120.00018.28
8.0.180.0110.00317.99
8.0.170.0320.00017.95
8.0.160.0160.00617.82
8.0.150.0090.00618.00
8.0.140.0120.00317.99
8.0.130.0120.00018.10
8.0.120.0120.00318.01
8.0.110.0090.00618.49
8.0.100.0100.00517.85
8.0.90.0150.00018.02
8.0.80.0110.00417.88
8.0.70.0140.00317.95
8.0.60.0170.00618.17
8.0.50.0290.00317.99
8.0.30.0150.00018.23
8.0.20.0210.00617.98
8.0.10.0170.00918.15

preferences:
28.41 ms | 403 KiB | 5 Q