拆分 foreach/for 循环以按部分插入 MySQL 数据库
Split a foreach/for loop to make inserts by parts into MySQL database
我有一个包含 300 万行的文档,我必须对其进行处理,然后将其插入到数据库的 table 中。数据库连接器 class 有一个插入和更新接收数据,然后进行操作。插入和更新工作完美。
问题是我想将此修改拆分到数据库以避免数据库过载。理想情况下,我希望自动拆分 n 行 arrFinal ,然后分别管理每个部分。但是我不知道该怎么做。
这是我现在拥有的 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
提前感谢您的帮助。我愿意尝试任何方法来解决这个问题。
好吧,对于初学者来说,您真的不需要所有 split
- 为什么要重新计算这么多次?
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 但它需要某种形式保存当前处理量以防万一应用失败。
多亏了另一个 post:
中的回答,我终于完成了我想要的事情
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]);
}
}
}
我有一个包含 300 万行的文档,我必须对其进行处理,然后将其插入到数据库的 table 中。数据库连接器 class 有一个插入和更新接收数据,然后进行操作。插入和更新工作完美。
问题是我想将此修改拆分到数据库以避免数据库过载。理想情况下,我希望自动拆分 n 行 arrFinal ,然后分别管理每个部分。但是我不知道该怎么做。
这是我现在拥有的 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
提前感谢您的帮助。我愿意尝试任何方法来解决这个问题。
好吧,对于初学者来说,您真的不需要所有 split
- 为什么要重新计算这么多次?
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
多亏了另一个 post:
中的回答,我终于完成了我想要的事情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]);
}
}
}