处理400万条记录时内存不足

本文关键字:内存不足 记录 400万 处理 | 更新日期: 2023-09-27 17:53:42

我有下面的代码,试图处理4,000,000条数据库记录:

private void intenseProcess4()
{
    using (connection1 = new SqlConnection("connection string goes here"))
    {
        using (command1 = new SqlCommand(@"stored procedure name goes here", connection1))
        {
            command1.CommandType = CommandType.StoredProcedure;
            try
            {
                connection1.Open();
                using (reader1 = command1.ExecuteReader())
                {
                    while (reader1.Read())
                    {
                        int PrjNameIndex1 = reader1.GetOrdinal("full_path");
                        Directory.CreateDirectory(Path.Combine(reader1.GetString(PrjNameIndex1)));
                    }
                    if (reader1.NextResult())
                    {
                        while (reader1.Read())
                        {
                            System.IO.File.Copy(reader1.GetString(SourceIndex), reader1.GetString(DestinationIndex), true);
                        }
                    }
                }
            }
            catch (SqlException ex)
            {
                File.AppendAllText(Path.Combine(@"h:'X'log'error.log"), ex + " SqlException caught." + Environment.NewLine);
            }
        }
    }
}

一旦启动,它可以正常工作大约一个小时,但随后它给出以下错误消息:

Problem signature:
    Problem Event Name: CLR20r3
    Problem Signature 01:   devenv.exe
    Problem Signature 02:   12.0.21005.1
    Problem Signature 03:   524fcb34
    Problem Signature 04:   mscorlib
    Problem Signature 05:   4.0.30319.34209
    Problem Signature 06:   534894cc
Problem Signature 07:   226e
Problem Signature 08:   6
Problem Signature 09:   System.OutOfMemoryException
OS Version: 6.1.7601.2.1.0.256.49
Locale ID:  2057
Additional Information 1:   0a9e
Additional Information 2:   0a9e372d3b4ad19135b953a78882e789
Additional Information 3:   0a9e
Additional Information 4:   0a9e372d3b4ad19135b953a78882e789

在那段时间里,它只处理了大约35000条记录

处理400万条记录时内存不足

Try with CommandBehavior.SequentialAccess:

当您指定SequentialAccess时,您需要按照列返回的顺序从列中读取,尽管您不需要读取每个列。一旦读取了返回的数据流中的某个位置,就不能再从DataReader中读取该位置或之前的数据。

但是试图在一次通过 4M记录中处理的智慧是值得怀疑的。我很确定您将永远无法成功复制4M文件,保持结果集打开。你注定要一次又一次地尝试。考虑使用批处理,检索一小部分文件来处理、复制、记录进度,然后再进行批处理。在崩溃的情况下,从最后的进度恢复。

您还应该考虑并行执行多个副本(使用异步IO,而不是线程!)

使用终端命令而不是GUI来创建存档