【发布时间】:2021-09-14 12:39:34
【问题描述】:
这么快的背景。我正在设置代码以将在许多方面一团糟的遗留数据库迁移到 Entity Framework Core 中的新数据库设计代码。我为新数据库制作了新模型,并在 ef core 中自动生成了旧数据库以简化操作。
我正在创建的其中一个表基于旧数据库中的 2 个表,它们具有基本相同的数据(但模型不同),它们加起来代表略超过 300,000 行。因此,我在新数据库中创建了 300,000 个新数据库模型及其相关表,总计约 120 万行。
我的问题是,当我运行大约 1000 行的测试并推断完成整个迁移的时间时,它大约需要 3.5 小时。即使对于如此大量的行,这也感觉很慢。
请注意,这两个数据库都在我的计算机上,因此任何网络延迟都不会影响它
下面是我的代码逻辑示例:
//old rows are selected earlier in the function from the legacyDbContext
//provider = IServiceProvider. I use dependency injection for this
foreach(var oldRow in oldRows)
{
using(var scope = provider.CreateScope())
{
var legacyDbContext = scope.ServiceProvider.GetRequiredService<LegacyDbContext>();
var newDatabaseDbContext = scope.ServiceProvider.GetRequiredService<NewDatabaseDbContext>();
var newRow = new NewRow();
newDatabaseContext.NewRows.Add(newRow);
newDatabaseContext.SaveChanges(); //generates the id for the newRow
//transfer data from oldRow to newRow with some very light processing
//Example
newRow.Name = oldRow.Name;
newRow.IsActive = Convert.ToBoolean(oldRow.IsActive)
//for some reason boolean values were saved as C# short ints
//which corresponds to tinyint on the database side
var oldRelatedItems = legacyDbContext.oldRelatedItems
.Where(m => m.oldItemId = oldItem.Id)
.ToList();
//in generally this list's count is only 2, sometimes 3
foreach(var oldRelatedItem in oldRelatedItems)
{
var newRelatedItem = new NewRelatedItem();
newDatabaseContext.NewRelatedItems.Add(newRelatedItem);
newRelatedItem.newItem = newItem;
//transfer data from oldRelatedItem to newRelatedItem
newDatabaseContext.SaveChanges();
}
//Some more data transferred
newDatabaseContext.SaveChanges();
}
}
这里需要注意的是旧数据库没有任何外键。有些列包含其他表中的行 ID,但它们没有配置为外键(我告诉过你这个数据库很乱)。所以这可能会成为一个瓶颈。
我尝试了几件大都无效的事情。我尝试完全在 using 语句中运行 foreach 循环,最后只保存上下文 1 次。这节省了一些时间,但不多(5 分钟 215 左右)。
我也尝试将 for 循环作为 Parallel.ForEach 循环运行,但实际上使用这种方法会增加外推时间(虽然我可能错误地使用了这个函数)。
对如何提高代码性能有任何想法吗?最终迁移只需运行 1 次,因为整个项目正在从头开始重建(这真的很糟糕)。尽管如此,为了我自己的理解,我还是想知道如何改进这一点,这样迁移可能不会需要几天时间(请记住,这个问题只针对几个表)。
【问题讨论】:
-
在我看来,精心设计的 SQL 语句执行起来会比这段代码快得多。
标签: c# sql asp.net-core entity-framework-core ef-core-3.1