gpt4 book ai didi

c# - 无法使用 C# 从 SQL Server 中选择超过 700000 行

转载 作者:行者123 更新时间:2023-11-30 15:52:58 25 4
gpt4 key购买 nike

我无法使用 C# 从 SQL Server 获取超过 700000 行 - 我收到“内存不足”异常。请帮帮我。

这是我的代码:

using (SqlConnection sourceConnection = new SqlConnection(constr))
{
sourceConnection.Open();

SqlCommand commandSourceData = new SqlCommand("select * from XXXX ", sourceConnection);

reader = commandSourceData.ExecuteReader();
}

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(constr2))
{
bulkCopy.DestinationTableName = "destinationTable";

try
{
// Write from the source to the destination.
bulkCopy.WriteToServer(reader);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
reader.Close();
}
}

我已经根据给定的解决方案 1 制作了小型控制台应用程序,但最终出现了同样的异常,我也发布了我的内存过程之前和之后处理前:enter image description here

After Processing

在读取代码端添加命令超时后,Ram Peaks up, enter image description here

最佳答案

该代码不应导致 OOM 异常。当您将 DataReader 传递给 SqlBulkCopy.WriteToServer 时,您正在将行从源流式传输到目标。在某处 else 你在内存中保留了一些东西。

SqlBulkCopy.BatchSize控制 SQL Server 提交在目标加载的行的频率,限制锁定持续时间和日志文件增长(如果不是最低限度记录和简单恢复模式)。是否使用一批对 SQL Server 或客户端中使用的内存量没有影响。

这是一个在不增加内存的情况下复制 1000 万行的示例:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SqlBulkCopyTest
{
class Program
{
static void Main(string[] args)
{
var src = "server=localhost;database=tempdb;integrated security=true";
var dest = src;

var sql = "select top (1000*1000*10) m.* from sys.messages m, sys.messages m2";

var destTable = "dest";

using (var con = new SqlConnection(dest))
{
con.Open();
var cmd = con.CreateCommand();
cmd.CommandText = $"drop table if exists {destTable}; with q as ({sql}) select * into {destTable} from q where 1=2";
cmd.ExecuteNonQuery();
}

Copy(src, dest, sql, destTable);
Console.WriteLine("Complete. Hit any key to exit.");
Console.ReadKey();
}

static void Copy(string sourceConnectionString, string destinationConnectionString, string query, string destinationTable)
{
using (SqlConnection sourceConnection = new SqlConnection(sourceConnectionString))
{
sourceConnection.Open();

SqlCommand commandSourceData = new SqlCommand(query, sourceConnection);

var reader = commandSourceData.ExecuteReader();

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnectionString))
{
bulkCopy.BulkCopyTimeout = 60 * 10;
bulkCopy.DestinationTableName = destinationTable;
bulkCopy.NotifyAfter = 10000;
bulkCopy.SqlRowsCopied += (s, a) =>
{
var mem = GC.GetTotalMemory(false);
Console.WriteLine($"{a.RowsCopied:N0} rows copied. Memory {mem:N0}");
};
// Write from the source to the destination.
bulkCopy.WriteToServer(reader);

}
}
}


}
}

哪些输出:

. . .
9,830,000 rows copied. Memory 1,756,828
9,840,000 rows copied. Memory 798,364
9,850,000 rows copied. Memory 4,042,396
9,860,000 rows copied. Memory 3,092,124
9,870,000 rows copied. Memory 2,133,660
9,880,000 rows copied. Memory 1,183,388
9,890,000 rows copied. Memory 3,673,756
9,900,000 rows copied. Memory 1,601,044
9,910,000 rows copied. Memory 3,722,772
9,920,000 rows copied. Memory 1,642,052
9,930,000 rows copied. Memory 3,763,780
9,940,000 rows copied. Memory 1,691,204
9,950,000 rows copied. Memory 3,812,932
9,960,000 rows copied. Memory 1,740,356
9,970,000 rows copied. Memory 3,862,084
9,980,000 rows copied. Memory 1,789,508
9,990,000 rows copied. Memory 3,903,044
10,000,000 rows copied. Memory 1,830,468
Complete. Hit any key to exit.

关于c# - 无法使用 C# 从 SQL Server 中选择超过 700000 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53482002/

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