改进我的代码来循环1000个csv文件,并更快地导入数百万条记录

本文关键字:导入 记录 数百万 文件 代码 我的 循环 csv 1000个 | 更新日期: 2023-09-27 18:08:55

我有1000个csv文件,每个csv文件包含5500行数据和8列。我下面的代码花了5分钟将一个csv文件导入MySQL数据库。我知道有很多这样的问题,我一直在调查。但是,根据我的代码,你有什么建议来改进这个导入过程吗?

private void btn_fetchSharePrices_Click(object sender, EventArgs e)
{
    string[] fileCSV = Directory.GetFiles(sourceDirCSV);
    foreach (string csv in fileCSV)
    {
        try
        {
            string[] lines = File.ReadAllLines(csv);
            foreach (var line in lines)
            {
                var data = line.Split(new[] { ',' }, 8);
                DateTime prices_date = DateTime.Parse(data[0].Trim());
                DateTime prices_time = DateTime.Parse(data[1].Trim());
                string open = data[2].Trim();
                string high = data[3].Trim();
                string low = data[4].Trim();
                string close = data[5].Trim();
                int volume = int.Parse(data[6].Trim());
                int tickers_ticker_id = int.Parse(data[7].Trim());
                StoreRecord_FetchSharePrices(prices_date, prices_time, open, high, low, close, volume, tickers_ticker_id);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }  
    }
}
private void StoreRecord_FetchSharePrices(DateTime prices_date, DateTime prices_time, string open, string high, string low, string close, int volume, int tickers_ticker_id)
{
    using (var connection = new MySqlConnection(strProvider))
    using (var command = connection.CreateCommand())
    {
        connection.Open();
        command.CommandText = @"INSERT IGNORE INTO prices (Prices_Date, Prices_Time, Prices_Open, Prices_High, Prices_Low, Prices_Close, Prices_Volume, Tickers_Ticker_ID) VALUES (@Prices_Date, @Prices_Time, @Prices_Open, @Prices_High, @Prices_Low, @Prices_Close, @Prices_Volume, @Tickers_Ticker_ID)";
        command.Parameters.AddWithValue("@Prices_Date", prices_date);
        command.Parameters.AddWithValue("@Prices_Time", prices_time);
        command.Parameters.AddWithValue("@Prices_Open", open);
        command.Parameters.AddWithValue("@Prices_High", high);
        command.Parameters.AddWithValue("@Prices_Low", low);
        command.Parameters.AddWithValue("@Prices_Close", close);
        command.Parameters.AddWithValue("@Prices_Volume", volume);
        command.Parameters.AddWithValue("@Tickers_Ticker_ID", tickers_ticker_id);
        command.ExecuteNonQuery();
    }
}

改进我的代码来循环1000个csv文件,并更快地导入数百万条记录

更快?在MySQL

load data local infile 'file.csv' into table table_name
 fields terminated by ','
 enclosed by '"'
 lines terminated by ''n'
 (column1, column2, column3,...)

对文件夹Directory.EnumerateFiles(Folder_path)中的文件运行foreach循环,并对每个具有完整文件路径(代替file.csv)的文件运行上述命令

Directory.EnumerateFiles()代替Directory.GetFiles()

看到文档:

EnumerateFiles和GetFiles方法的不同之处在于:当你使用EnumerateFiles时,你可以在返回整个集合之前开始枚举名称集合;当您使用GetFiles时,您必须等待整个名称数组返回,然后才能访问该数组。因此,当您处理许多文件和目录时,EnumerateFiles可以更有效。

您可以尝试使用LOAD DATA INFILE命令,参见链接。

我认为这是最好的选择。

您可以编写一个小程序来为每个CSV文件启动此命令。

您可以使用批量插入命令:

BULK
INSERT prices 
FROM 'your file name'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = ''n'
)