我见过多个线程讨论这个问题,但答案中总是有完全不同的结论。特别是我想知道是否真的有必要创建一个自己的准备好的语句(带有适量的占位符)以便将其作为单个查询插入。 我预计当我在 for 循环之前和之后使用 beginTransaction
和 endTransaction
时,pdo/php 会等待事务,直到收集到所有数据一旦服务器到达 endTransaction
行,它就会将这些数据作为单个查询发送。
我需要如何重写这样的带有多次插入的 for 循环插入才能达到最佳性能(通常有 1 到 300 行,但也可能达到 2000 行)。
for($i=0; $i<$baseCount; $i++)
{
$thLevel = $bases[$i]["ThLevel"];
$gold = $bases[$i]["Gold"];
$elixir = $bases[$i]["Elixir"];
$darkElixir = $bases[$i]["DarkElixir"];
$dateFound = $elixir = $bases[$i]["TimeFound"];
$query = $db->prepare("INSERT INTO bot_attacks_searchresults (attack_id, available_gold, available_elixir, available_dark_elixir, date_found, opponent_townhall_level)
VALUES (:attack_id, :available_gold, :available_elixir, :available_dark_elixir, :date_found, :opponent_townhall_level)");
$query->bindValue(':attack_id', $attackId);
$query->bindValue(':available_gold', $gold);
$query->bindValue(':available_elixir', $elixir);
$query->bindValue(':available_dark_elixir', $darkElixir);
$query->bindValue(':date_found', $dateFound);
$query->bindValue(':opponent_townhall_level', $thLevel);
$query->execute();
}
最佳答案
准备声明一次。 MySQL 对它进行一次词法分析,因此对查询的任何后续调用都会很快,因为它已经进行了词法分析并且只需要参数。
在循环之前启动事务。这样做是为了让您的硬盘可以在一次输入输出操作中写下所有行。默认模式是1次插入查询=1次硬盘I/O。
创建循环,在其中绑定(bind)参数并调用
$query->execute();
退出循环并
commit()
事务。
完整代码:
$db->beginTransaction();
$query = $db->prepare("INSERT INTO bot_attacks_searchresults (attack_id, available_gold, available_elixir, available_dark_elixir, date_found, opponent_townhall_level)
VALUES (:attack_id, :available_gold, :available_elixir, :available_dark_elixir, :date_found, :opponent_townhall_level)");
for($i = 0; $i < $baseCount; $i++)
{
$thLevel = $bases[$i]["ThLevel"];
$gold = $bases[$i]["Gold"];
$elixir = $bases[$i]["Elixir"];
$darkElixir = $bases[$i]["DarkElixir"];
$dateFound = $elixir = $bases[$i]["TimeFound"];
$query->bindValue(':attack_id', $attackId);
$query->bindValue(':available_gold', $gold);
$query->bindValue(':available_elixir', $elixir);
$query->bindValue(':available_dark_elixir', $darkElixir);
$query->bindValue(':date_found', $dateFound);
$query->bindValue(':opponent_townhall_level', $thLevel);
$query->execute();
}
$db->commit();
关于php - 尽可能快地插入多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32034538/