使用.NET将1000000条记录更新(填充)到数据库中的最快方法
本文关键字:数据库 方法 填充 NET 1000000条 记录 更新 使用 | 更新日期: 2023-09-27 18:19:47
我使用这段代码将100万条记录插入数据库中的一个空表中。好的,在没有太多代码的情况下,我将从我已经与数据交互的点开始,并将模式读取到DataTable
:中
因此:
DataTable returnedDtViaLocalDbV11 = DtSqlLocalDb.GetDtViaConName(strConnName, queryStr, strReturnedDtName);
现在我们有了returnedDtViaLocalDbV11
,让我们创建一个新的DataTable
作为源数据库表的克隆:
DataTable NewDtForBlkInsert = returnedDtViaLocalDbV11.Clone();
Stopwatch SwSqlMdfLocalDb11 = Stopwatch.StartNew();
NewDtForBlkInsert.BeginLoadData();
for (int i = 0; i < 1000000; i++)
{
NewDtForBlkInsert.LoadDataRow(new object[] { null, "NewShipperCompanyName"+i.ToString(), "NewShipperPhone" }, false);
}
NewDtForBlkInsert.EndLoadData();
DBRCL_SET.UpdateDBWithNewDtUsingSQLBulkCopy(NewDtForBlkInsert, tblClients._TblName, strConnName);
SwSqlMdfLocalDb11.Stop();
var ResSqlMdfLocalDbv11_0 = SwSqlMdfLocalDb11.ElapsedMilliseconds;
此代码将在5200ms中向嵌入式SQL数据库(localDb)填充100万条记录。其余的代码只是实现bulkCopy,但我无论如何都会发布它。
public string UpdateDBWithNewDtUsingSQLBulkCopy(DataTable TheLocalDtToPush, string TheOnlineSQLTableName, string WebConfigConName)
{
//Open a connection to the database.
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[WebConfigConName].ConnectionString))
{
connection.Open();
// Perform an initial count on the destination table.
SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM "+TheOnlineSQLTableName +";", connection);
long countStart = System.Convert.ToInt32(commandRowCount.ExecuteScalar());
var nl = "'r'n";
string retStrReport = "";
retStrReport = string.Concat(string.Format("Starting row count = {0}", countStart), nl);
retStrReport += string.Concat("==================================================", nl);
// Create a table with some rows.
//DataTable newCustomers = TheLocalDtToPush;
// Create the SqlBulkCopy object.
// Note that the column positions in the source DataTable
// match the column positions in the destination table so
// there is no need to map columns.
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = TheOnlineSQLTableName;
try
{
// Write from the source to the destination.
for (int colIndex = 0; colIndex < TheLocalDtToPush.Columns.Count; colIndex++)
{
bulkCopy.ColumnMappings.Add(colIndex, colIndex);
}
bulkCopy.WriteToServer(TheLocalDtToPush);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
// Perform a final count on the destination
// table to see how many rows were added.
long countEnd = System.Convert.ToInt32(
commandRowCount.ExecuteScalar());
retStrReport += string.Concat("Ending row count = ", countEnd, nl);
retStrReport += string.Concat("==================================================", nl);
retStrReport += string.Concat((countEnd - countStart)," rows were added.", nl);
retStrReport += string.Concat("New Customers Was updated successfully", nl, "END OF PROCESS !");
//Console.ReadLine();
return retStrReport;
}
}
通过与SQL服务器的连接进行尝试大约需要7000ms(最多)&平均7700ms。同样,通过一个随机的kv-nosql数据库需要大约40秒(实际上,我甚至没有记录它,因为它通过了x2个sql变体)。那么…有没有比我在代码中测试的更快的方法?
编辑
我使用的是win7 x64 8gb内存,最重要的是我应该认为(作为i5 3ghz)现在还不是很好Raid-0上的x3 500Gb Wd做得更好但我只是说,如果你能检查一下你的电脑尽管只需将其与配置中的任何其他方法进行比较
您尝试过SSIS吗?我从未编写过具有locldb连接的SSIS包,但SSIS应该非常适合这种活动。
如果您的数据源是SQL Server,另一个想法是设置一个链接服务器。不确定这是否适用于localdb。如果你可以设置一个链接服务器,你可以绕过C#,用INSERT加载你的数据。。选择。。。来自。。。SQL语句。
您可以使用Dapper.NET
。Dapper是一个微型ORM,执行查询并将结果映射到强类型列表。计算机软件中的对象关系映射(ORM、O/RM和O/R映射)是一种在面向对象编程语言中用于在不兼容类型系统之间转换数据的编程技术。这实际上创建了一个"虚拟对象数据库",可以在编程语言中使用
更多信息:
结账https://code.google.com/p/dapper-dot-net/
GitHub存储库:https://github.com/SamSaffron/dapper-dot-net希望有帮助。。
删除循环。。。在SQL中,尝试创建一个包含100万行的表。。。并且左联接它将此用于插入/选择数据
尝试在不将其存储在数据表中的情况下发送它。
请参阅本文末尾的示例,该示例允许您使用枚举器进行操作http://www.developerfusion.com/article/122498/using-sqlbulkcopy-for-high-performance-inserts/
如果您只是在创建无意义的数据,请创建一个存储过程并通过.net 调用它
如果您正在传递真实的数据,再次将其传递到存储过程会更快,但最好删除表并用数据重新创建它。
如果一次插入一行,将比一次插入所有行花费更长的时间。如果要编写索引,则需要更长的时间。
为要保存到数据库中的所有行创建一个单独的XML文件。将此XML传递给SQL存储过程,并仅在一次调用中保存所有记录。但必须编写存储过程,这样它才能读取所有读取然后插入到表中。
如果这是一个新项目,我建议您使用实体框架。在这种情况下,您可以创建一个列表<>使用一个包含所有所需数据的对象,然后简单地将其完全添加到相应的表中。通过这种方式,您可以快速获取所需的数据,然后立即将其发送到数据库。
我同意Mike对SSIS的看法,但它不适合您的环境,但是对于涉及跨服务器调用和通用数据流过程的ETL过程,它是一个很好的内置工具,并且高度集成。
对于100万行,您可能需要进行大容量插入。根据行大小的不同,除非分批执行,否则您将无法真正使用存储过程。数据表会很快填满内存,这同样取决于行大小。你可以制作一个存储过程,让它采用一个表类型,并每X行调用一次,但当你已经有了更好、更可扩展的解决方案时,我们为什么要这样做呢。那一百万排明年可能是五千万排。
我曾经使用过SSIS,如果它适合组织,我建议查看它,但它不会是一次性的答案,也不值得依赖。