有這樣一個表
CREATE TABLE IF NOT EXISTS `user_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
`name` varchar(255) NOT NULL default '' COMMENT '姓名',
`age` int(11) NOT NULL default '0' COMMENT '年齡',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶信息表';
批量插入
方法一、使用for循環插入
在往mysql插入少量數據的時候,我們一般用foreach或者(for)循環
$arr = [
[
'name' => 'name1',
'age' => 18,
],
[
'name' => 'name2',
'age' => 19,
],
[
'name' => 'name3',
'age' => 18,
],
];
foreach($arr as $key=>$values){
//這裏是tp5.0的寫法
Db::name('user_info')->insert($values);
}
假如說要批量插入大量數據,如果還用foreach或者(for)循環的辦法插入是沒有問題的,只是時間會比較長。不過有時超出php代碼執行時間,會出現中斷
對比一下插入少量數據與插入大量數據,使用上面的foreach或者(for)循環插入耗費的時間:當然這也是粗略計算時間
條數 | 時間(單位:秒) |
---|---|
10 | 0.011 |
1000 | 0.585 |
10000 | 5.733 |
100000 | 60.587 |
方法二、使用insert語句合併插入
mysql裏面是可以使用insert語句進行合併插入的,比如INSERT INTO user_info (name, age) VALUES ('name1', 18), ('name2', 19);
表示一次插入兩條數據
$arr = [
[
'name' => 'name1',
'age' => 18,
],
[
'name' => 'name2',
'age' => 19,
],
[
'name' => 'name3',
'age' => 18,
],
];
Db::name('user_info')->insertAll($values);
下面看一下少量數據與大量數據的時間對比。從總體時間上,可以看出insert合併插入比剛纔for循環插入節約了很多時間,效果很明顯
條數 | 時間(單位:秒) |
---|---|
10 | 0.006 |
1000 | 0.025 |
10000 | 0.131 |
100000 | 1.23 |
以下是對insertAll分析
/**
* 批量插入記錄
* @access public
* @param mixed $dataSet 數據集
* @param boolean $replace 是否replace
* @param integer $limit 每次寫入數據限制
* @return integer|string
*/
public function insertAll(array $dataSet, $replace = false, $limit = null)
{
// 分析查詢表達式
$options = $this->parseExpress();
if (!is_array(reset($dataSet))) {
return false;
}
// 生成SQL語句
if (is_null($limit)) {
//array_chunk將數組切成指定大小的塊,然後對每個塊進行insert合併插入.
$sql = $this->builder->insertAll($dataSet, $options, $replace);
} else {
$array = array_chunk($dataSet, $limit, true);
foreach ($array as $item) {
$sql[] = $this->builder->insertAll($item, $options, $replace);
}
}
// 獲取參數綁定
$bind = $this->getBind();
if ($options['fetch_sql']) {
// 獲取實際執行的SQL語句
return $this->connection->getRealSql($sql, $bind);
} elseif (is_array($sql)) {
// 執行操作
return $this->batchQuery($sql, $bind, $this);
} else {
// 執行操作
return $this->execute($sql, $bind, $this);
}
}
若想你的代碼高效,最好用方式2,執行時間短