PHP - 为什么要使用这么多内存来读取这个csv文件,我该如何改进我的代码呢?

时间:2014-01-16 13:56:34

标签: php mysql csv import laravel

情况是我需要将一个相当大的csv文件(大约一百万条记录--80mb)导入mysql数据库。我知道我可以从命令行执行此操作,但我需要UI,因此客户端可以执行此操作。

这是我到目前为止所做的:

ini_set('max_execution_time', 0);
ini_set('memory_limit', '1024M');

$field_maps = array();

foreach (Input::get() as $field => $value){
if ('fieldmap_' == substr($field, 0, 9) && $value != 'unassigned'){
    $field_maps[str_replace('fieldmap_', null, $field)] = $value;
    }
}
$file = app_path().'/../uploads/'.$client.'_'.$job_number.'/'.Input::get('file');

$result_array = array();
$rows = 0;
$bulk_insert_count = 1000; 
if (($handle = fopen($file, "r")) !== FALSE)
{
    $header = fgetcsv($handle);
    $data_map = array();
    foreach ($header as $k => $th){
        if (array_key_exists($th, $field_maps)){
             $data_map[$field_maps[$th]] = $k;
        }
    }

    $tmp_rows_count = 0;
    while (($data = fgetcsv($handle, 1000)) !== FALSE) {
        $row_array = array();

        foreach ($data_map as $column => $data_index){
            $row_array[$column] = $data[$data_index];
        }

        $result_array[] = $row_array;
        $rows++;
        $tmp_rows_count++;

        if ($tmp_rows_count == $bulk_insert_count){
            Inputs::insert($result_array);
            $result_array = array();
            if (empty($result_array)){
                echo '*************** array cleared *************';
            }
            $tmp_rows_count = 0;
        }
    }
    fclose($handle);
}
print('done');

我目前正在研究一个本地流浪盒,当我尝试在本地运行上面它几乎处理csv文件的所有行然后在结束前不久就死掉(没有错误)但是它起到了盒子内存限制为1.5Gb。

我怀疑我在上面的代码中所做的一些事情是不必要的,例如但是我想通过构建和插入有限数量的行来减少内存使用但是做得还不够。

我怀疑这可能会在具有更多可用内存的实时服务器上运行,但我无法相信它必须采用1.5Gb内存来处理80mb文件,必须有更好的方法。任何帮助非常感谢

1 个答案:

答案 0 :(得分:1)

有这个问题一次,这解决了我:

DB::connection()->disableQueryLog();

有关它的文档中的信息:http://laravel.com/docs/database#query-logging