【问题标题】:Split a foreach/for loop to make inserts by parts into MySQL database拆分 foreach/for 循环以按部分插入 MySQL 数据库
【发布时间】:2022-01-12 11:52:22
【问题描述】:

我有一个包含 300 万行的文档,我必须对其进行处理,然后将其插入数据库的表中。数据库连接器类具有接收数据然后进行操作的插入和更新。插入和更新工作完美。

问题是我想将此修改拆分到数据库以避免数据库过载。理想情况下,我希望自动拆分 arrFinaln 行,然后分别管理每个部分。但我不知道该怎么做。

这是我现在拥有的 foreach:

ConnectDB cdb = new ConnectDB();

foreach (string s in arrFinal)
{
    if (s.Split(';')[1] == "REQUEST")
    {
        cdb.Insert(s.Split(';')[0], s.Split(';')[2], s.Split(';')[3], s.Split(';')[4], s.Split(';')[5], dateLog);
    }
    else if (s.Split(';')[1] == "RESPONSE")
    {
        cdb.Update(s.Split(';')[0], s.Split(';')[5]);
    }
}

如果您想知道数据是如何来的:

00:00:00.7443;REQUEST;POST;https://ulrName/Prices/;/1_0/962;https://ulrName/Prices/1_0/962
00:00:00.7793;RESPONSE;POST;https://ulrName/Prices/;/1_0/962;https://ulrName/Prices/1_0/962

提前感谢您的帮助。我愿意尝试任何方法来解决这个问题。

【问题讨论】:

  • 你好。假设 arrFinal 是您的最终数组,包含 300 万行。如果可能的话,也许最好不要在 RAM 中收集那么多记录/行。相反,也许您可​​以将“从文档中读取”划分为具有诸如startingLineIndex和LineCountLimit等参数的较小作业。然后创建函数来读取预定的行数,然后应用插入/更新行,然后再次读取该行数然后插入/update 等。这可能是更好的做法,然后阅读所有行然后尝试处理它们。

标签: c# mysql for-loop foreach


【解决方案1】:

嗯,对于初学者来说,你真的不需要所有的splits - 为什么要重新计算这么多次?

ConnectDB cdb = new ConnectDB();

foreach (string s in arrFinal)
{
    var data = s.Split(';')
    if (data[1] == "REQUEST")
    {
        cdb.Insert(data[0], data[2], data[3], data[4], data[5], dateLog);
    }
    else if (data[1] == "RESPONSE")
    {
        cdb.Update(data[0], data[5]);
    }
}

你也可以使用spans之类的东西。

至于拆分数组:

public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
    using var enumerator = source.GetEnumerator();
    while (enumerator.MoveNext()) 
    {
        yield return YieldBatchElements(enumerator, batchSize - 1);
    }
}

private static IEnumerable<T> YieldBatchElements<T>(IEnumerator<T> source, int batchSize)    
{
    yield return source.Current;    for (var i = 0; i < batchSize && source.MoveNext(); i++)    
    yield return source.Current;
}

要一次性获得所有结果,只需在使用Batch() 扩展方法时在末尾附加.ToList()

另一件事是尝试加载文件的一部分并处理它,然后是另一部分,另一个等等,例如 AntiqTech mentioned 但它需要以某种形式保存当前处理的数量,以防应用程序失败。

【讨论】:

  • 谢谢你的回答,古怪!我采取了不同的方法,我正在发布在这种情况下对我有用的方法。我还要感谢您对我所做的许多拆分的建议。
【解决方案2】:

感谢另一个帖子中的这个答案,我终于设法完成了我想要的事情:

How to split an array into chunks of specific size?

我的最终代码是这样的:

String[][] chunks = arrFinal
                    .Select((s, i) => new { Value = s, Index = i })
                    .GroupBy(x => x.Index / 500)
                    .Select(grp => grp.Select(x => x.Value).ToArray())
                    .ToArray();

ConnectDB cdb = new ConnectDB();

for (int i = 0; i < chunks.Length; i++)
{
    foreach (string s in arrFinal)
    {
        var data = s.Split(';'); 
        if (data[1] == "REQUEST")
        {
            cdb.Insert(data[0], data[2], data[3], data[4], data[5], dateLog);
        }
        else if (data[1] == "RESPONSE")
        {
            cdb.Update(data[0], data[5]);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 2020-02-02
    • 2012-06-19
    • 2015-12-25
    • 1970-01-01
    • 2021-07-07
    相关资源
    最近更新 更多