假設有一張表 A(id, name, title, addtime),需要插入 N 條記錄。早期常見做法是構造 N 條獨立的 INSERT 語句,循環調用執行:
$sql1 = "INSERT INTO `A`(`name`,`title`,`addtime`) VALUES ('name1','title1','".$time."')";
$sql2 = "INSERT INTO `A`(`name`,`title`,`addtime`) VALUES ('name2','title2','".$time."')";
...
$sqlN = "INSERT INTO `A`(`name`,`title`,`addtime`) VALUES ('nameN','titleN','".$time."')";
這種方式存在明顯缺點:
MySQL 支持 VALUES 子句後跟多組值,用逗號分隔:
$sql = "INSERT INTO `A`(`name`,`title`,`addtime`) VALUES ('name1','title1','".$time."'),";
$sql .= "('name2','title2','".$time."'),";
$sql .= "('name3','title3','".$time."'),";
...
$sql .= "('nameN','titleN','".$time."')";
測試環境:插入 30 條記錄
結論:批量插入快近 9 倍!
單條 INSERT ... VALUES (...), (...), ... 在 MySQL 中具有原子性:
這讓數據一致性管理變得極其簡單,無需顯式事務控制。
$b = 14;
for ($a = 0; $a < 100; $a++) {
$sql = "INSERT INTO `roles` (`uid`,`rid`) VALUES (".$a.",".$b.")";
mysql_query($sql); // 100 次網絡往返
}
$b = 14;
$sql = "";
for ($a = 0; $a < 100; $a++) {
if ($a == 0) {
$sql = "INSERT INTO `roles` (`uid`,`rid`) VALUES (".$a.",".$b.")";
} else {
$sql .= ",(".$a.",".$b.")";
}
}
mysql_query($sql); // 僅 1 次網絡往返
max_allowed_packet 限制,建議每 500~1000 條分批提交mysqli_stmt_bind_param 批量綁定參數,防注入且性能更優經驗之談: phpMyAdmin 導出的 SQL 文件正是採用這種多值 VALUES 格式,這也是其導入速度極快的原因之一。