十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
1、建议你读写数据和下载图片分开,各用不同的进程完成。
创新互联为企业级客户提高一站式互联网+设计服务,主要包括网站设计、成都网站设计、app软件开发、微信小程序定制开发、宣传片制作、LOGO设计等,帮助客户快速提升营销能力和企业形象,创新互联各部门都有经验丰富的经验,可以确保每一个作品的质量和创作周期,同时每年都有很多新员工加入,为我们带来大量新的创意。
比如说,取数据用get-data.php,下载图片用get-image.php。
2、多进程的话,php可以简单的用pcntl_fork()。这样可以并发多个子进程。
但是我不建议你用fork,我建议你安装一个gearman worker。这样你要并发几个,就启几个worker,写代码简单,根本不用在代码里考虑thread啊,process等等。
3、综上,解决方案这样:
(1)安装gearman worker。
(2)写一个get-data.php,在crontab里设置它每5分钟执行一次,只负责读数据,然后把读回来的数据一条一条的扔到 gearman worker的队列里;
然后再写一个处理数据的脚本作为worker,例如叫process-data.php,这个脚本常驻内存。它作为worker从geraman 队列里读出一条一条的数据,然后跟你的数据库老数据比较,进行你的业务逻辑。如果你要10个并发,那就启动10个process-data.php好了。处理完后,如果图片地址有变动需要下载图片,就把图片地址扔到 gearman worker的另一个队列里。
(3)再写一个download-data.php,作为下载图片的worker,同样,你启动10个20个并发随便你。这个进程也常驻内存运行,从gearman worker的图片数据队列里取数据出来,下载图片
4、常驻进程的话,就是在代码里写个while(true)死循环,让它一直运行好了。如果怕内存泄露啥的,你可以每循环10万次退出一下。然后在crontab里设置,每分钟检查一下进程有没有启动,比如说这样启动3个process-data worker进程:
* * * * * flock -xn /tmp/process-data.1.lock -c '/usr/bin/php /process-data.php /dev/null 21'
* * * * * flock -xn /tmp/process-data.2.lock -c '/usr/bin/php /process-data.php /dev/null 21'
* * * * * flock -xn /tmp/process-data.3.lock -c '/usr/bin/php /process-data.php /dev/null 21'
不知道你明白了没有
下载 PHPExcel
require_once( './PHPExcel/IOFactory.php');
$filePath = 'D:/xxx.xlsx'; //excel 文件名
$objReader = new PHPExcel_Reader_Excel2007(); //具体查看(Documentation/Examples/Reader/exampleReader01.php)
$objPHPExcel = $objReader-load($filePath);
$sheetData = $objPHPExcel-getActiveSheet()-toArray(null,true,true,true);
$insql = 'insert into 表名(x,x,x) valeus';
//遍历数组 $sheetData
//如果有标题 先删除 unset($sheetData[1]);
foreach($sheetData as $k = $data){
$insql .= '('.$data['A'].','.$data['B'].','.$data['C'].'),';
//一次插入100条数据 减少数据库压力
if(($k+1 / 100) == 0){
$insql = rtrim($insql,',').';'; //将最后的逗号替换成分好
//插入数据库 并且重置 字符串 $insql
//或者保存到文件中 利用source 命令插入数据库
}
}
优化SQL插入语句;
比如循环一条一条插入,改成链接多个值进行插入。
将:
foreach($re as $it){
$sql="insert into table (id,name) values(".$it['id'].","."$it['name'].")";
mysql_query($sql);
}
改为:
$sql="insert into table (id,name) values";
foreach($re as $it){
$str= "'".$it['id']."','".$it['name']."'";
}
$sql .= "(".$str."),";
$sql2 = substr($sql,0,-1);
mysql_query($sql);
打开mysql的配置文件,my.ini文件,并找到:max_allowed_packet项;
将值修改大一点,具体根据自己需要修改。比如这里修改为:1G。
重启mysql服务;
5
如果运行页面提示内存溢出,可将值设大一点。
Allowed memory size of 134217728 bytes exhausted (tried to allocate 132907287 bytes)
步骤阅读
6
这样,面对千万数据导入的时候,比原来那种方法至少快好多倍。