我有一个脚本,读取大约10k行文本文件,每行有一个电子邮件地址。对于每个地址,我检查它是否已经被使用,如果是,我将地址放入error
数组,如果没有,我将地址放入save
数组。
在foreach之后,如果错误数组中没有地址,则执行$this->Newsletter->saveMany($data)
。
由于某种原因,当我导入超过500行时,我总是得到一个超时。是否有另一种更好的方法来避免超时?
请建议!
public function import() {
$filename = './files/newsletterImport/newsletter.txt';
$lines = file($filename);
foreach ($lines as $line_num => $line) {
// check unique
if($email = $this->Newsletter->find('first', array('conditions' => array('email' => trim($line))))){
$error[$line_num]['email'] = trim($line);
$error[$line_num]['cancel'] = date('d.m.Y H:i:s', strtotime($email['Newsletter']['cancel']));
}else{
$data[$line_num]['Newsletter']['email'] = trim($line);
$data[$line_num]['Newsletter']['active'] = 1;
}
}
if(!$error){
$this->Newsletter->create();
if($this->Newsletter->saveMany($data)){
$this->set('msg', 'Success');
}else{
$this->set('msg', 'Error! Nothing imported!');
}
}else{
$this->set('msg', 'Error! Nothing imported!');
$this->set('error', $error);
}
}else{
$this->set('msg', 'No file found!');
}
既然你真的不知道什么时候超时了,这里有一些小建议。
1)测量每个代码位的时间,除非你知道哪一部分占用了你最多的时间。
2)你为每一行对DB做一个查询,这是10k的查询值…我的心很痛。因此,考虑执行一个大查询来获取所有电子邮件,并将它们与php进行比较,以了解它们是否唯一。再次验证一下,也许SQL选项更有效(取决于您如何在PHP数组上进行搜索)
3)尝试调整保存选项。默认情况下,原子选项为true,这对于保存10k可能有点太大了。
$this->Newsletter->saveMany($data, array('atomic'=>false));
如果这些不能解决问题,尝试将数组划分并按阶段保存。