2014-01-20 238 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