目前我有一个大约1000万条记录的平面文件。
我首先读取文件并将列映射到数据表中。然后从Datatable使用SQLBulkCopy将其移动到数据库中。这是一个缓慢的过程,并且会耗费很多时间。
我想知道这个过程是否可以做得更好。
1)I.e。而不是将我的1000万条记录加载到数据表中,然后加载到数据库中。是否更好地加载"块" 100万进入数据表并在循环中处理它们直到所有处理?或者,如果任何人对如何改进这个过程有任何建议,我将不胜感激!
foreach (var line in File.ReadLines(fileLocation + @"\" + filename))
{
var dataColumns = line.Split('\t');
var dr = dt.NewRow();
for (var i = 0; i < dataColumns.Length; i++)
{
dr[i] = dataColumns[i].Trim().Length == 0 ? null : dataColumns[i];
}
dt.Rows.Add(dr);
}
using (var destinationConnection = new SqlConnection(Settings.Default.ConnectionString))
{
var tableName = filename.Substring(0, filename.IndexOf('.'));
destinationConnection.Open();
try
{
using (var createAndDropTableCommand = new SqlCommand("sp_DropAndCreateTable", destinationConnection))
{
createAndDropTableCommand.CommandType = CommandType.StoredProcedure;
createAndDropTableCommand.Parameters.Add("@TableToCreate", SqlDbType.VarChar).Value = tableName;
createAndDropTableCommand.ExecuteNonQuery();
}
using (var bulkCopy = new SqlBulkCopy(destinationConnection))
{
bulkCopy.DestinationTableName = "dbo." + tableName;
bulkCopy.BatchSize = 10000;
bulkCopy.ColumnMappings.Clear();
foreach (DataColumn col in dt.Columns)
{
bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(col.ColumnName, col.ColumnName));
}
bulkCopy.WriteToServer(dt);
}
}
finally
{
destinationConnection.Close();
}
}
答案 0 :(得分:0)
你肯定是在正确的轨道上 SQL批量复制应该能够在大约30秒内处理超过一百万条记录。我在dbsourcetools.codeplex.com中使用了DataBets和SQLBulkCopy
System.Data.DataSet oDataSet = new System.Data.DataSet();
oDataSet.ReadXmlSchema(strSchemaXml);
oDataSet.ReadXml(strTableXml);
if (oDataSet.Tables.Count > 0)
{
using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(oTargetDatabase.ConnectionString))
{
conn.Open();
System.Data.SqlClient.SqlTransaction oTran = conn.BeginTransaction();
System.Data.SqlClient.SqlBulkCopy oSqlBulkCopy
= new System.Data.SqlClient.SqlBulkCopy(conn, System.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity, oTran);
oSqlBulkCopy.BulkCopyTimeout = 600;
oSqlBulkCopy.BatchSize = 1000;
oSqlBulkCopy.DestinationTableName = strFullyQualifiedTableName;
oSqlBulkCopy.NotifyAfter = 10000;
oSqlBulkCopy.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(oSqlBulkCopy_SqlRowsCopied);
foreach (System.Data.DataColumn ocol in oDataSet.Tables[0].Columns)
{
oSqlBulkCopy.ColumnMappings.Add(ocol.ColumnName, ocol.ColumnName);
}
oSqlBulkCopy.WriteToServer(oDataSet.Tables[0]);
oTran.Commit();
conn.Close();
}
System.Console.WriteLine("Wrote : " + oDataSet.Tables[0].Rows.Count.ToString() + " records ");
}