gpt4 book ai didi

c# - 遍历很多行

转载 作者:行者123 更新时间:2023-11-30 17:13:31 25 4
gpt4 key购买 nike

我在循环遍历数据库中大约 100 万个潜在行时遇到了时间问题。我基本上将行拉入 DataTable 并循环遍历它们,但速度越来越慢。那里有什么选择?我可以将这些行分成 20,000 block 这样的 block 。我可以在 C# 中使用并行处理吗?基本上,代码循环遍历与特定查询匹配的每个潜在记录,并尝试确定它是否是合法条目。这就是为什么需要单独访问每条记录的原因。一个对象的记录可能达到 1000 万行。方法似乎是在多台计算机上并行处理或在多核单机上并行处理,或者某种数据结构/方法更改?

有什么意见、想法和猜测有助于使这个变得快速和合理吗?

最佳答案

首先:不要使用 DataTable 进行这些操作:

  • 它很慢
  • 太占内存了
  • 并且您需要等待很长时间才能真正开始处理数据
    • 在此期间,额外的内核什么都不做,因为将数据读入 DataTable 并未并行化。
    • 此外,在读取数据时,CPU 通常几乎没有得到充分利用,因为网络或其他 I/O 延迟通常是主要因素。

再说一遍:不要将 DataTable 用于此类操作。

改为使用DataReader。这允许您立即开始使用/处理数据,而不是等待数据加载。最简单的版本是(MS SQL Server 示例):

var command = new SqlCommand()
{
CommandText = "SELECT * FROM Table";
Connection = new SqlConnection("InsertConnectionString");
};

using(var reader = command.ExecuteReader())
{
while(reader.Read())
{
var values = new object[reader.FieldCount];
reader.GetValues(values);

// process values of row
}
}

读取器在执行您的处理代码时将被阻塞,这意味着不再从数据库读取行。
如果处理代码很重,使用 Task 库来创建执行检查的任务可能是值得的,这将使您能够利用多个内核。但是,创建 Task 会产生开销,如果一个 Task 没有包含足够的“工作”,您可以将几行批处理在一起:

public void ReadData()
{
var taskList = new List<Task<SomeResultType>>();

var command = new SqlCommand()
{
CommandText = "SELECT * FROM Table";
Connection = new SqlConnection("InsertConnectionString");
};
using(var reader = command.ExecuteReader())
{
var valueList = new List<object[]>(100);
while(reader.Read())
{
var values = new object[reader.FieldCount];
reader.GetValues(values);

valueList.Add(values);

if(valueList.Count == 100)
{
var localValueList = valueList.ToList();
valueList.Clear();

taskList.Add(Task<SomeResultType>.Factory.StartNew(() => Process(localValueList));
}
}
if(valueList.Count > 0)
taskList.Add(Task<SomeResultType>.Factory.StartNew(() => Process(valueList));
}

// this line completes when all tasks are done
Task.WaitAll(taskList.ToArray());
}

public SomeResultType Process(List<object[]> valueList)
{
foreach(var vals in valueList)
{
// put your processing code here, be sure to synchronize your actions properly
}
}
  • 批量大小(目前为 100)取决于实际进行的处理,可能需要调整。
  • 同步有其自身的挑战,您需要非常小心共享资源

关于c# - 遍历很多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9651716/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com