使用PDO向MySQL插入1000行的有效方法

时间:2013-04-07 12:49:56

标签: php mysql pdo

每次我必须在MySQL中插入1000行数据。目前,我使用PDO和for循环逐行插入数据库。有没有更有效的方法来实现更好的性能?因为我必须将max_execution_time设置为5分钟。

function save()
{
            return $query = $this->insert("
                INSERT INTO gadata (landing_page, page_title, page_views, visits, visitors, bounce_rate, pageviews_per_visit, time_on_page, avg_time_on_page, day, month, year, hour)
                VALUES (:landing_page, :page_title, :page_views, :visits, :visitors, :bounce_rate, :pageviews_per_visit, :time_on_page, :avg_time_on_page, :day, :month, :year, :hour)", $this->data);
}

protected function insert($sql, array $data) {
    $q = $this->_db_handler->prepare($sql);

    foreach ($data as $k => $v)
    {
       $q->bindValue(':' . $k, $v);
    }

    $q->execute();
}

3 个答案:

答案 0 :(得分:2)

它不是PDO,也不是你插入的方式使插入如此延迟,而是 innodb 引擎。所以你有3个选择:

  1. 将所有插入内容包装到事务中。
  2. 使用root权限,将innodb_flush_log_at_trx_commit变量设置为2,使innodb使用文件缓存进行写入 - 这将使您的插入速度极快。
  3. 按照Manu
  4. 的建议在一个查询中运行所有插入

答案 1 :(得分:1)

可能不是最佳解决方案,但您可以尝试构建一个查询字符串,如INSERT INTO [table] VALUES (r1c1,r1c2,r1c3),(r2c1,r2c2,r2c3) ...并执行一个mysql_query(或者说一个查询几百行),您甚至可以以编程方式验证数据构建sql查询,如果它不是来自可靠来源。

答案 2 :(得分:1)

参数化查询按定义交易执行安全性,以减少数据项计数的灵活性。

您至少有两种可能性可以缓解:

  • 构建SQL,然后立即执行:

类似的东西:

$sql="INSERT INTO gadata (landing_page, page_title, page_views, visits, visitors, bounce_rate, pageviews_per_visit, time_on_page, avg_time_on_page, day, month, year, hour) VALUES ";
foreach ($all_data_rows as $data) {
  if ($i==0) $value=""; else $value=",";
  $sql.=$value."(:landing_page$i, :page_title$i, :page_views$i, :visits$i, :visitors$i, :bounce_rate$i, :pageviews_per_visit$i, :time_on_page$i, :avg_time_on_page$i, :day$i, :month$i, :year$i, :hour$i)";
  $i++;
}
$i=0;
$q=$db_handler->prepare($sql);
foreach ($all_data_rows as $data) {
  foreach ($data as $k => $v) {
    $q->bindValue(":$k$i", $v);
  }
  $i++;
}
$q->execute();
  • 使用临时表来避免锁定和磁盘开销

首先创建一个类型为HEAP的临时表,其结构与目标表相同,然后插入其中:这将更快,因为没有锁定和磁盘IO发生。然后运行

INSERT INTO final_table SELECT * FROM temporary_table

如果缓解不够,则需要考虑对此用例使用非参数化查询。通常的警告适用。