我问了一个关于在准备好的语句中进行多次插入(数百甚至数千)的性能方面的最佳方法的问题。请参阅此处 How to perform multiple MySQL inserts in PHP 。
在回答问题的过程中,这个老问题又出现了:下面是否真的发生了多次SQL调用? :
$stmt = $dbLink->prepare( "INSERT INTO table SET id = :ID,
name = :name,
email = :email,
mobile = :mobile");
$stmt->bindParam( ':ID', $person->getID(), PDO::PARAM_STR );
$stmt->bindParam( ':name', $person->getName(), PDO::PARAM_STR );
$stmt->bindParam( ':email', $person->getEmail(), PDO::PARAM_STR );
$stmt->bindParam( ':mobile', $person->getMobile(), PDO::PARAM_STR );
foreach( $persons as $person ){
$stmt->execute();
}
拜托,我认为这样的事情不能同时是对和错。这一定是有事实依据的;我只是不知道这个事实。
最佳答案
首先,您应该稍微重新排序代码:
$person
未在循环外部定义(或者不是您所想的那样),因此您会收到警告,并且bindParam
将设置空值<- 您将在
for
循环中插入相同的(空)值,因为您从未更新查询参数。
这样做,就像 explained in this answer 一样:
$stmt = $dbLink->prepare( "INSERT INTO table SET id = :ID,
name = :name,
email = :email,
mobile = :mobile");
foreach ( $persons as $person ) {
$stmt->bindParam( ':ID', $person->getID(), PDO::PARAM_STR );
$stmt->bindParam( ':name', $person->getName(), PDO::PARAM_STR );
$stmt->bindParam( ':email', $person->getEmail(), PDO::PARAM_STR );
$stmt->bindParam( ':mobile', $person->getMobile(), PDO::PARAM_STR );
$stmt->execute();
}
其次,每次运行$stmt->execute()
时,您都在执行查询。因此,您将运行 count( $persons )
查询。准备好的语句稍微快一点,因为 SQL 查询字符串只需解析一次。
即使对于数千条记录,这也会运行得非常快。然而,每次数据库写入磁盘时,您可能会遇到延迟;这对于软件 RAID 和慢速磁盘尤其明显。您可以使用 transactions 消除除其中一个延迟之外的所有延迟。 :
$dbLink->beginTransaction();
$stmt = $dbLink->prepare( ..... );
foreach ( $persons as $person ) {
...bindParam();
...execute();
}
$dbLink->commit();
关于php - : when placed before execution, PDO准备好的语句是否进行多次sql调用到底是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34241795/