通过php数组将多行插入mysql

too*_*ays 126 php mysql bulkinsert codeigniter insert

我正在使用插入命令通过PHP将大型数据集传递到MySQL表中,我想知道是否可以通过查询一次插入大约1000行,而不是将每个值附加到一英里长字符串的末尾然后执行它.我正在使用CodeIgniter框架,因此我也可以使用它的功能.

sta*_*san 226

INSERT使用多行组装一个语句在MySQL中要比INSERT每行一个语句快得多.

也就是说,听起来你可能会遇到PHP中的字符串处理问题,这实际上是一个算法问题,而不是语言问题.基本上,在处理大字符串时,您希望尽量减少不必要的复制.首先,这意味着您要避免连接.构建大型字符串的最快和最高效的内存方式,例如在一个字符串中插入数百行,就是利用implode()函数和数组赋值.

$sql = array(); 
foreach( $data as $row ) {
    $sql[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')';
}
mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $sql));
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是您不会复制和重新复制到目前为止与每个连接组装的SQL语句; 相反,PHP 在声明中执行了一次implode().这是一个很大的胜利.

如果你有很多列放在一起,并且一个或多个列很长,你也可以构建一个内部循环来做同样的事情,并用于implode()将values子句赋值给外部数组.

  • 感谢那!如果有人计划复制它,你可以在函数末尾找到一个右括号.mysql_real_query('INSERT INTO table VALUES(text,category)'.implode(','.$ sql)); (5认同)
  • 谢谢!固定.(我经常这样做......) (3认同)
  • 我相信这段代码将为我的最新项目创建一个解决方案.我的问题是,这是否可以安全地从SQL注入?我的计划是用`mysqli_real_escape_string`和`mysql_query`和`mysqli_query`切换出'mysql_real_escape_string`,因为我正在使用MySQLi,这些已经从PHP5开始被弃用了.非常感谢! (3认同)
  • 此查询容易受到 sql 注入! (2认同)
  • `mysql_*`已经从PHP中删除了,所以一定要使用`mysqli_*`接口. (2认同)

Som*_*luk 59

codeigniter现在支持多个插入/批量插入.我有同样的问题.虽然回答问题已经很晚了,但它会对某些人有所帮助.这就是回答这个问题的原因.

$data = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name' ,
      'date' => 'My date'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name' ,
      'date' => 'Another date'
   )
);

$this->db->insert_batch('mytable', $data);

// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最推荐的多行插入方式,而不是使用 mysql_query。因为当我们使用框架时,始终使用框架的内置功能是一个很好的做法。 (2认同)

Esp*_*Boy 20

您可以使用mysqli_stmt类准备查询以插入一行,然后迭代数据数组.就像是:

$stmt =  $db->stmt_init();
$stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)");
foreach($myarray as $row)
{
    $stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']);
    $stmt->execute();
}
$stmt->close();
Run Code Online (Sandbox Code Playgroud)

其中'idsb'是您要绑定的数据类型(int,double,string,blob).

  • 我最近运行了一些比较批量插入和准备插入语句的基准测试,如此处所述.对于大约500个刀片,准备好的刀片方法在2.6-4.4秒之间完成,并且批量插入方法在0.12-0.35秒内完成.我原本以为mysql会将这些准备好的语句"批量"放在一起,并且与批量插入一样好,但在默认设置中,性能差异显然是巨大的.(顺便说一下,所有基准测试查询都在每个测试的单个事务中运行,以防止自动提交) (5认同)

小智 15

我知道这是一个旧的查询,但我只是阅读并认为我会添加我在其他地方找到的内容:

PHP 5中的mysqli是一个具有一些好功能的ojbect,可以让你加快上面答案的插入时间:

$mysqli->autocommit(FALSE);
$mysqli->multi_query($sqlCombined);
$mysqli->autocommit(TRUE);
Run Code Online (Sandbox Code Playgroud)

在插入许多行时关闭自动提交会大大加快插入速度,因此将其关闭,然后执行如上所述,或者只创建一个字符串(sqlCombined),这是由分号分隔的多个插入语句,多查询将处理它们.

希望这可以帮助别人节省时间(搜索和插入!)

[R


vez*_*ult 7

你总是可以使用mysql的LOAD DATA:

LOAD DATA LOCAL INFILE '/full/path/to/file/foo.csv' INTO TABLE `footable` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' 
Run Code Online (Sandbox Code Playgroud)

进行批量插入而不是使用一堆INSERT语句.


bdl*_*bdl 5

好吧,你不想执行1000个查询调用,但这样做很好:

$stmt= array( 'array of statements' );
$query= 'INSERT INTO yourtable (col1,col2,col3) VALUES ';
foreach( $stmt AS $k => $v ) {
  $query.= '(' .$v. ')'; // NOTE: you'll have to change to suit
  if ( $k !== sizeof($stmt)-1 ) $query.= ', ';
}
$r= mysql_query($query);
Run Code Online (Sandbox Code Playgroud)

根据您的数据源,填充数组可能就像打开文件并通过内容将内容转储到数组一样简单file().