首页 > 解决方案 > 如何优化大型 CSV 文件数据提取的循环

问题描述

我有一个关于代码优化的问题。十多年来,除了简单的循环之外,我没有编写任何代码。

我创建了下面的代码,它工作得很好,但对我的需要来说超级慢。

本质上,我有 2 个 CSV 文件:

对于源文件中的每个 source_id,我的代码都会在主文件中解析 main_id == source_id 的所有行,并将这些行中的每一行写入一个新文件中。

你对我如何优化代码有什么建议吗?

<?php

$mf = "main.csv";
$mf_max_line_length = "512";
$mf_id = "main_id";

$sf = "source.csv";
$sf_max_line_length = "884167";
$sf_id = "source_id";


if (($mf_handle = fopen($mf, "r")) !== FALSE)
{
    // Read the first line of the main CSV file
    // and look for the position of main_id
    $mf_data = fgetcsv($mf_handle, $mf_max_line_length, ",");
    $mf_id_pos = array_search ($mf_id, $mf_data);

    // Create a new main CSV file
    if (($nmf_handle = fopen("new_main.csv", "x")) !== FALSE)
    {
        fputcsv($nmf_handle,$mf_data);
    } else {
        echo "Cannot create file: new_main.csv" . $sf;
        break;
    }
}

// Open the source CSV file
if (($sf_handle = fopen($sf, "r")) !== FALSE)
{
    // Read the first line of the source CSV file
    // and look for the position of source_id
    $sf_data = fgetcsv($sf_handle, $sf_max_line_length, ",");
    $sf_id_pos = array_search ($sf_id, $sf_data);

    // Go trhough the whole source CSV file
    while (($sf_data = fgetcsv($sf_handle, $sf_max_line_length, ",")) !== FALSE)
    {
        // Open the main CSV file
        if (($mf_handle = fopen($mf, "r")) !== FALSE)
        {
            // Go trhough the whole main CSV file
            while (($mf_data = fgetcsv($mf_handle, $mf_max_line_length, ",")) !== FALSE)
            {
                // If the source_id matches the main_id
                // then we write it into the new_main CSV file
                if ($mf_data[$mf_id_pos] == $sf_data[$sf_id_pos])
                {
                    fputcsv($nmf_handle,$mf_data);
                }
            }
            fclose($mf_handle);
        }
    }
    fclose($sf_handle);
    fclose($nmf_handle);
}

?>

标签: phpfileloopscsv

解决方案


听起来像是 mysql 的工作。

首先,您需要根据所有字段创建表。看这里

然后,您将加载数据。 看这里

最后,您将创建如下查询:

SELECT * INTO OUTFILE '/tmp/something.csv' 
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' 
    LINES TERMINATED BY '\n' 
FROM source_table INNER JOIN main_table ON 
    source_table.source_id=main_table.main_id;

推荐阅读