[英]console app slow to exit if sqlbulkcopy.writetoserver is used
[英]SqlBulkCopy.WriteToServer(DataTable) row by row: very slow
我必须制作将csv
文件导入数据库表的应用程序。 该csv
文件类似于~500rows
~30columns
和距离不是很可靠的消息来源(可能包含损坏的数据)。
我像这样CSV->DataTable->SqlBulkCopy.WriteToServer(DataTable)
做到了。 并且它将500条记录处理到非本地sql服务器大约4秒钟 ,这不是什么大问题。 但是,由于csv可能包含损坏的数据(错误的日期格式,整数溢出等),因此我不得不使其出错,并导入好行并跳过坏行。 将损坏的数据处理到DataTable时,但将DataTable导入到DataBase时,不会发生问题。 我所做的是TRY {}这样在数据库中逐行添加。
int Row = 0;
//csvFileData is the DataTable filled with csv data
foreach(DataRow RowToAdd in csvFileData.Rows)
{
//here it spents 1-2% of the time (problem not in DT row by row processing)
Row++;
DataTable TempDT = new DataTable();
TempDT = csvFileData.Clone();
TempDT.ImportRow(RowToAdd);
try
{
//here it spents 98% of the time
s.WriteToServer(TempDT);
}
catch(Exception importex)
{
Console.WriteLine("Couldn't import {0} row, reason", Row, importex.Message);
}
}
调用: s.WriteToServer(scvFileData);
就我而言,一次是不好的。
结束它确实很好。 问题在于执行时间增加到15秒,这很多。 因为它确实与数据库的每一行进行前进和后退通信。 我怎样才能解决这个问题。 我正在考虑模拟诸如数据库表设计的本地克隆之类的东西。 尝试{}在其上逐行尝试,然后排除不良行,然后将整个DataTable(已删除不良行)导入。 或者逐行执行一些异步导入,但是我认为行可能会按顺序乱码,或者丢失甚至重复。 有人可以给个小费吗?
一行的批量插入比单行的插入慢10倍以上。 您当前的策略不起作用。
验证并清除客户端上的数据。 必须保证插入成功。 将其复制到DataTable
。 一次全部插入,或至少插入大量(插入的性能开始出现在100或1000行中)。
如上所述,一种明显的解决方案是验证从CSV文件读取的数据,并仅用“好行”填充数据表。
如果您的验证包括数据类型检查,即,如果字符串可以由目标系统(此处为SQL-Server)转换,则可以在此处复制逻辑,即,重新编程已在SQL Server中实现的解析/转换逻辑。 这不是一个大问题,但是从设计角度来看并不一定很聪明。
实际上,您可以使用BULK INSERT
命令将CSV文件直接导入SQL-Server。
因此,另一种方法可能是将原始数据导入服务器中的临时表中,然后进行数据类型检查。 当您碰巧运行SQL 2005或更高版本时,这非常容易。 他们介绍了ISDATE
和ISNUMERIC
类的函数。
BULK INSERT CSVRawData FROM 'c:\csvtest.txt' WITH (
FIELDTERMINATOR = ',', ROWTERMINATOR = '\n'
)
INSERT INTO FinalTable
SELECT * from CSVRawData
WHERE ISDATE(DateField)
and ISNUMERIC (NumericField)
如果发生以下情况,我个人将采用这种方式:
例如,我们以这种方式分析日志文件。 它们包含50个Mio +行,其中一些已损坏,或者我们根本不感兴趣。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.