首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >pdo一次插入太多行的有效方法

pdo一次插入太多行的有效方法
EN

Stack Overflow用户
提问于 2015-05-24 09:04:19
回答 2查看 2.4K关注 0票数 2

我正在以编程的方式将行从excel文件导入到数据库。excel文件有10列* 30000行。我在php数组中导入了这些数据,然后将其插入数据库中。

上传文件后,需要7-8分钟才能插入数据库中的所有行。我知道两种插入行的方法

第一方法:

生成动态查询,

代码语言:javascript
运行
复制
INSERT INTO table_name (col1, col2,..) VALUES (row1, row1, ....), (row2, row2, ....), (row3, row3, ....), (row4, row4, ....), ...

并运行查询以插入所有行。

第二种方法:

代码语言:javascript
运行
复制
$con->prepare("INSERT INTO table_name (col1, col2, ...) VALUES (:col1, :col2, ...)");
foreach ($rows as $row) { // Loop through all rows and insert them
    $result->bindParam(':col1', $val1);
    $result->bindParam(':col2', $val2);
    $result->bindParam(':col3', $val3);
    ...
    ...
    $result->execute();
}

第一似乎混乱和低效,我正在使用第二种方法,但它只插入500-700行每秒,并需要7-8分钟的时间来插入所有的行。

还有哪些方法比这些方法更有效、更快?

编辑:不要建议直接将excel文件导入mysql。在插入数据库之前需要对数据进行处理。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-24 10:24:01

尝试将您的SQL封装到事务中,然后在结束时重复您的数据。这将释放大量的资源,因为注释数据做了相当多的工作(它告诉您的DB保存您正在插入的数据,并重新索引-假设您有这些数据)。

另外,尝试确保数据库的连接是池的-这意味着您不会每次从DB抓取一个新的连接,而是使用相同的连接。

但是,使用事务的风险是,如果数据集中发生一个错误(防止插入),它将回滚整个数据集。

像这样的东西能起作用..。

代码语言:javascript
运行
复制
<?php
  try {
    $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', 
      array(PDO::ATTR_PERSISTENT => true)); // POOLED
      echo "Connected\n";
  } catch (Exception $e) {
    die("Unable to connect: " . $e->getMessage());
  }

  try {  
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $dbh->beginTransaction();
    $dbh->prepare("INSERT INTO table_name (col1, col2, ...) VALUES (:col1, :col2, ...)");
    foreach ($rows as $row) { // Loop through all rows and insert them

      // I am not sure where you define $result
      // Review in your implementation if you use
      $result->bindParam(':col1', $val1);
      $result->bindParam(':col2', $val2);
      $result->bindParam(':col3', $val3);
      ...
      ...
      $result->execute();
    }

  } catch (Exception $e) {
    $dbh->rollBack();
    echo "Failed: " . $e->getMessage();
  }


  $dbh->commit();

?>
票数 1
EN

Stack Overflow用户

发布于 2015-05-24 10:18:57

最快的方法是将数百个插入包包装到事务和提交中。MySQL将使用硬盘驱动器的单个输入/输出操作来编写许多记录--这是快速的。

代码语言:javascript
运行
复制
$con->prepare("INSERT INTO table_name (col1, col2, ...) VALUES (:col1, :col2, ...)");

$inserts = 1000;
$counter = 0;

foreach ($rows as $row) { // Loop through all rows and insert them

    if($counter === 0 && !$con->inTransaction()) {
        $con->beginTransaction();
    }

    $result->bindParam(':col1', $val1);
    $result->bindParam(':col2', $val2);
    $result->bindParam(':col3', $val3);
    ...
    ...
    $result->execute();

    $counter++;

    if($counter === $inserts) {
        $con->commit();
    }    
}

if($con->inTransaction()) {
    $con->commit();
    $counter = 0;
}

上面的代码应该在每执行1000次插入后提交。我还没有测试它,所以它很可能包含错误,但是它的目的是说明如何在事务中包装1000个插入并提交它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30421766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档