2014-01-20 210 views
0

我正在查看导入CSV文件,但此文件相当大。导入大型CSV文件

我正在寻找做的,就是两两件事:,我

1) Scan the CSV to validate values in particular fields 
2) Once the file is valid, import 

CSV数据可以ONLY将文件是否有效插入(全有或全无)

的问题是m循环两次,第一次检查CSV字段是否有效,然后另一个for循环保存。

问题是内存。内存不足(文件为100,000行,包含45个字段)

是否有更简单的方法来执行此操作并减少内存?我正在使用AR实现,会使用PDO更快吗?

感谢

编辑:

 $data = array(); 
     // open the file and loop through 
     if(($handle = fopen('details.csv', "r")) !== FALSE) { 
      $rowCounter = 0; 
      while (($rowData = fgetcsv($handle, 0, ",")) !== FALSE) { 
       if(0 === $rowCounter) { 
        $headerRecord = $rowData; 
       } else { 
        foreach($rowData as $key => $value) { 
         $data[ $rowCounter - 1][$headerRecord[ $key] ] = $value; 
        } 
       } 
       $rowCounter++; 
      } 
      fclose($handle); 
     } 

     $errors = array(); 
     // loop to check through the fields for validation 
     for($i=0;$i<count($data);$i++) { 
      $row++; 

      if(!valid_email($data[$i]['EMAIL']))) { 
       $errors[] = 'Invalid Email Address'; 
       break; 
      } 

     } 

     if(empty($errors)) { 
      for($j=0;$j<count($assocData);$j++) { 
      $row++; 

      $details = new Details(); 

      // set the fields here 
      $details->email = $data[$j]['EMAIL']; 

      $details->save(); 
      unset($details); 
      } 
     } 
+0

您可以使用'fopen'和'fgets'并一次一行地手动解析它。你的意思是“有效”? – h2ooooooo

+0

我们可能必须查看您的代码才能帮助您减少内存使用量。另外,您应该插入一个事务中,而不是逐行插入。 – mcryan

+0

@ h2ooooooo我在字段方面进行了验证(必须是一个以99开始的数字并且是15个字符长度等)。我使用'fopen'和'fgetcsv'来打开和解析 –

回答

0

你已经通过数据循环在你第一次foreach。为什么不验证循环中的字段,如果验证通过添加到数组以保存并且只有在循环完成时才保存(在单个事务中)。

+0

在单个事务中保存这些数据的性能如何?该文件可能会增加到1,000,000行加上! –

+0

这也意味着你可以在数据库上执行1,000,000次操作,当你可以在1中完成所有操作!多次循环播放结果也是完全不必要的,绝对是性能杀手。 – mcryan