【发布时间】:2020-06-06 21:00:47
【问题描述】:
使用 C# 我正在尝试从 csv 文件(约 55000 条记录)插入具有 350 列的 postgresql table。我只是从逗号分隔的标题和记录中构建insert statement。
像这样:
INSERT INTO public.table(field1,fields2,field3, ..... ,field350) VALUES(?,?,?,?,?,.......,?);
INSERT INTO public.table(field1,fields2,field3, ..... ,field350) VALUES(?,?,?,?,?,.......,?);
INSERT INTO public.table(field1,fields2,field3, ..... ,field350) VALUES(?,?,?,?,?,.......,?);
INSERT INTO public.table(field1,fields2,field3, ..... ,field350) VALUES(?,?,?,?,?,.......,?);
....etc
我尝试使用 batch,比如收集 1000 条语句并在 transaction 中执行它们,但这需要 1000 条记录,最多约 3 秒。
我尝试按照 Microsoft here 的示例进行操作,其中我在每一行上调用 ExecuteNonQuery(),但在 1000 条记录后我 commit transaction 并开始一个新的 transcation,这正在占用每 1000 条记录约 3 秒。像这样的:
foreach (var line in ReadCsvFileToList(dataFile))
{
try
{
if (firstLine)
{
header = line;
firstLine = false;
continue;
}
else
{
var formattedLine = line.Replace("\"\"", "NULL").Replace("'", "''").Replace("\"", "'");
var commandText = $"INSERT INTO public.table({header.Replace('/', '_')}) VALUES ({formattedLine})";
command.CommandText = commandText;
await command.ExecuteNonQueryAsync();
round++;
}
if (round == 1000) // batch size
{
await transaction.CommitAsync();
Console.WriteLine("batch commited to DB at: " + DateTime.Now.ToString("ddMMyyy hh:mm:ss"));
round = 0;
transaction = connection.BeginTransaction();
}
}
catch (Exception)
{
await connection.CloseAsync();
await connection.DisposeAsync();
await transaction?.RollbackAsync();
throw;
}
}
关于如何进一步优化的想法?
【问题讨论】:
-
你似乎试图在没有native support的情况下解决这个问题。
-
也许这会有所帮助...stackoverflow.com/questions/38652832/…
标签: c# postgresql bulkinsert