php mysql插入1000万行_php实现mysql百万级数据插入,耗时10s左右

本文介绍了一个使用PHP CI框架实现批量导入百万条数据到MySQL的案例,通过循环和分批插入策略,使得整个过程在10秒内完成。文章详细展示了代码实现逻辑,包括参数验证和SQL语句的拼接。
摘要由CSDN通过智能技术生成

如题,最近做的一个项目,需求就是这样,写个功能模块,实现批量导入,为客服省点时间(好吧,需求就是需求)。好在插入的数据,都是些连续的数字,所以可以利用

foreach循环出这些数据,然后拼接成mysql的insert语句,进行大字段的批量插入。原理就是这么个原理,当然过程中有坑,什么打开扩展限制,暂且只看逻辑方面的吧。

框架的话,不是laravel,用的ci,实例代码如下:

/**

* @desc 批量导入百万条数据入库(暂时只有韵达,方法已经写通用,数据最少5000条,最大100W条)

* @date 2017-10-26 20:45:45

* @param [int $start_no 起始号;int $end_no 截止号;string $express_type 类型]

* @author 1245049149@qq.com

* @return [type]

*/

public function import_million_express_no () {

//基本数据设置

header(‘Content-Type:text/html;charset=utf-8‘);

ini_set(‘memory_limit‘, ‘128M‘);

//设置类型对应数据库中的表名

$express_to_form = [

‘test1‘ => ‘from1‘, //平台1对应的表名

‘test2‘ => ‘from2‘, //平台2对应的表名

];

//获取参数

$start_no = trim($this->input->post(‘start_no‘));

$end_no = trim($this->input->post(‘end_no‘));

$express_type = trim($this->input->post(‘express_type‘));

//判断参数是否存在

if(!$start_no || !$end_no){

echo ‘‘;

return;

}

//起始单号不能大于等于截止单号,录入数量至少为5000个

if ($start_no >= $end_no) {

echo ‘‘;

return;

} else {

if ($end_no - $start_no < 5000) {

echo ‘‘;

return;

}

if ($end_no - $start_no > 1000000) {

echo ‘‘;

return;

}

}

//判断数据类型是否存在

$table_name = $express_to_form[$express_type];

if(!$table_name){

echo ‘‘;

return;

}else{

//判断初始单号,截止单号是否已经录入

$sql1 = "select id from {$table_name} where express_no = {$start_no}";

$res1 = $this->db->query($sql1)->row();

if($res1){

echo ‘‘;

return;

}

$sql2 = "select id from {$table_name} where express_no = {$end_no}";

$res2 = $this->db->query($sql2)->row();

if($res2){

echo ‘‘;

return;

}

}

/***上面的一系列判断的废话可以不用看,直接看下面怎么对数据进行逻辑处理***/

//将起始号和截止号进行区间划分

$length = $end_no - $start_no + 1;

$times = floor($length / 5000);

$temp_data = [];

for($i=0;$i

$temp_data[$i][‘start_no‘] = $start_no; //起始编号

$temp_data[$i][‘end_no‘] = $start_no + 4999; //结束编号

$start_no += 5000; //下一轮循环的起始编号

}

//检验数组最后一组数据,判断是否需要再添加

if($end_no > $temp_data[$times-1][‘end_no‘]){

$temp_data[$times][‘start_no‘] = $temp_data[$times-1][‘end_no‘] + 1;

$temp_data[$times][‘end_no‘] = $end_no;

}

//进行导入数据库sql语句的拼接

$add_time = time();

$add_user = $this->session->userdata[‘user_name‘];

$tmp_val = "(‘{$add_time}‘,‘$add_user‘,0,‘%s‘,0),";

for($j=0;$j

//循环拼接sql插入语句

$sql = "insert into {$table_name} (field1,field2,field3,field4,field5) values ";

for ($i=$temp_data[$j][‘start_no‘]; $i<=$temp_data[$j][‘end_no‘]; $i++) {

$sql .= sprintf($tmp_val, $i);

}

$sql = trim($sql, ‘,‘) . ‘;‘;

$bool = $this->db->query($sql);

//执行插入有误,写进日志异常表from3中

if(!$bool){

// 记录日志

$log_info = array();

$log_info[‘field1‘] = time();

$log_info[‘field2‘] = ‘类型:‘.$express_type.‘执行有误,单号‘.$temp_data[$j][‘start_no‘].‘-‘.$temp_data[$j][‘end_no‘].‘执行失败‘;

$log_info[‘field3‘] = $this->session->userdata[‘user_name‘];

$this->db->insert(‘from3‘, $log_info);

//错误日志标志

$err_log_info = TRUE;

}

}

//数据返回

if($err_log_info){

echo ‘‘;

}else{

echo ‘‘;

}

return;

}

上面就是封装的一个完整的类,参数验证什么的,可以不用看了,直接看sql语句拼接,其实最后发现吧,做出来也没啥。经过测试,基本耗时在10s左右徘徊,恩恩,暂时先这样,有好的思路,欢迎交流。不说了,得继续加班去了,233

php实现mysql百万级数据插入,耗时10s左右

标签:imp   user   time()   rom   代码   存在   ack   导入   utf-8

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:http://www.cnblogs.com/qwgshare/p/7739461.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值