处理非常大的csv文件,没有超时和内存错误

Jul*_*ian 25 php csv import timeout

目前我正在编写一个非常大的CSV文件的导入脚本.问题大部分是由于超时而在一段时间后停止或者引发内存错误.

我的想法现在是以"100行"步骤解析CSV文件,然后100行自动调用脚本.我试图通过标题(位置...)实现这一点,并使用get传递当前行,但它没有按我想要的那样工作.

有没有更好的方法,或有人知道如何摆脱内存错误和超时?

fee*_*ela 52

我曾经fgetcsv以流的方式读取120MB的csv(这是正确的英语吗?).它逐行读取,然后我将每一行插入数据库.这样,每次迭代只在内存中保留一行.剧本仍然需要20分钟.跑步.也许我下次尝试Python ...不要尝试将巨大的csv文件加载到数组中,这会消耗大量内存.

// WDI_GDF_Data.csv (120.4MB) are the World Bank collection of development indicators:
// http://data.worldbank.org/data-catalog/world-development-indicators
if(($handle = fopen('WDI_GDF_Data.csv', 'r')) !== false)
{
    // get the first row, which contains the column-titles (if necessary)
    $header = fgetcsv($handle);

    // loop through the file line-by-line
    while(($data = fgetcsv($handle)) !== false)
    {
        // resort/rewrite data and insert into DB here
        // try to use conditions sparingly here, as those will cause slow-performance

        // I don't know if this is really necessary, but it couldn't harm;
        // see also: http://php.net/manual/en/features.gc.php
        unset($data);
    }
    fclose($handle);
}
Run Code Online (Sandbox Code Playgroud)


小智 16

我发现上传文件并使用mysql的LOAD DATA LOCAL查询快速解决方案,例如:

    $sql = "LOAD DATA LOCAL INFILE '/path/to/file.csv' 
        REPLACE INTO TABLE table_name FIELDS TERMINATED BY ',' 
        ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES";
    $result = $mysqli->query($sql);
Run Code Online (Sandbox Code Playgroud)


2nd*_*boy 13

如果您不关心它需要多长时间以及需要多少内存,您可以简单地增加此脚本的值.只需将以下行添加到脚本的顶部:

ini_set('memory_limit', '512M');
ini_set('max_execution_time', '180');
Run Code Online (Sandbox Code Playgroud)

使用函数memory_get_usage(),您可以找到脚本需要多少内存来为memory_limit找到一个好的值.

您可能还想查看fgets(),它允许您逐行读取文件.我不确定这是否需要更少的内存,但我真的认为这会起作用.但即使在这种情况下,您也必须将max_execution_time增加到更高的值.

  • 如果你知道它不大于特定尺寸,它也可以. (3认同)