在实体框架4的SQL CE 4.0中插入大量行(性能问题)

本文关键字:性能 问题 插入 框架 实体 SQL CE | 更新日期: 2023-09-27 18:05:21

我有一个小型SQL CE 4.0数据库,其中包含几个表,使用实体框架4进行映射。

下面是我的代码

foreach (String designation in newItemDesignations)
{
    ParameterData defaultValue = PDM.GetDefaultParameterData(designation);
    // Fill the ItemParameterDBO object with the data
    ItemParameterDBO dbParam = new ItemParameterDBO();
    dbParam.ItemID = dbItem.ID;
    dbParam.Designation = designation;    
    dbParam.High = defaultValue.High;
    dbParam.Low = defaultValue.Low;
    database.ItemParameterDBOes.AddObject(dbParam);
}
database.SaveChanges();

这个代码发生在24 times,每次newItemDesignations列表包含 exactly 525 elements 。总共要添加12600行。

完整进程持续 509 seconds 。我想这对12600行来说太多了。

我知道我正在呼叫SaveChanges 24 times。目前,应用程序设计不允许我将所有插入都放入单个事务中(使用SaveChanges)。但是,让我们看看单个事务发生了什么。 509 / 24 = 21 seconds ,或a 40 ms per row
  • 通过EF4插入一行的正常(平均)时间是40毫秒吗?

我已经检查了我的其他代码(除了添加到数据库和保存更改)。对于所有12600行,总共需要100 ms。这是完成时间的0.01%,所以这显然不是问题。99.99%的处理时间花在EF4 AddObjectSaveChanges上。

我也知道我正在设置ItemID属性,这是一个外键。这是一个整数,所以我想这不太重要。但我不知道。

还要注意:在任何表上都没有设置索引(除了主键/外键)

  • 我在这里做错了什么,为什么这么慢?
  • 这是插入那么多行所需的正常时间,还是与SQL CE 4相关的某种性能限制?

在实体框架4的SQL CE 4.0中插入大量行(性能问题)

由于示例很少,下面是我测试的代码,它完美地工作了。感谢ErikEJ's SqlCeBulkCopy库。A必须有。

DataTable table = new DataTable();
table.Columns.Add(new DataColumn("A", typeof(int)));
table.Columns.Add(new DataColumn("B", typeof(String)));
table.Columns.Add(new DataColumn("C", typeof(Byte)));
for(int i = 0; i < 12000; i++)
{
    DataRow row = table.NewRow();
    row["A"] = "124324"
    row["B"] = "something";
    row["C"] = 15;
    table.Rows.Add(row);
}
String connString = @"Data Source = C:'Database.sdf";
SqlCeBulkCopy bulkInsert = new SqlCeBulkCopy(connString);
bulkInsert.DestinationTableName = "Items";
bulkInsert.WriteToServer(table);

插入我的(OP) 12600行花了不到2秒。

这个例子很糟糕,它不是强类型的,但它描述了如何手动创建一个数据表,并使用SqlCeBulkCopy库将其插入到数据库中(参见链接的接受答案)。

您可以考虑使用我的SqlCeBulkCopy库,以绕过EF http://sqlcebulkcopy.codeplex.com

为了进一步了解ErikEJ的答案和您自己的示例,您可以在列表上使用IDataReader的实现,将数据流式传输到WriteToServer,而不是通过DataTable复制值。请看这个问题:

从类型化列表中获取IDataReader

我在工作中实现过一次,它似乎没有提高性能,但它似乎减少了内存消耗。