php - : when placed before execution, PDO准备好的语句是否进行多次sql调用到底是什么

标签 php mysql pdo insert prepared-statement

我问了一个关于在准备好的语句中进行多次插入(数百甚至数千)的性能方面的最佳方法的问题。请参阅此处 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/

相关文章:

php - 注册和登录密码哈希方法相同但不起作用

PHP foreach循环插入数据库

php - ajax请求中的laravel TokenMismatchException

javascript - 如何延迟 php 中输入字段的搜索功能,使其仅在键入 3 个字符后才开始搜索?

php - 带有重音字符的列

mysql - 如何使用新的 VPS 在非 root 帐户下安装 apache

php - 为什么 isset() 和 empty() 使用相同的操作码?

mysql - 查询优化(MySQL)

php - 构建 MySQL 表,其中 PLAYLIST 表引用多个 VIDEO id 整数和 USER 表 id

php - 长时间运行的作业和 SQL 事务