0
我试图导入大约900K行数据并将其映射到我的新数据模型。 我的问题是,我为此导入功能构建的控制台应用程序随着时间的推移而变慢。控制台应用程序随着时间推移减慢
我监视了SQL查询并且它们都表现良好(< 5ms)。 我试图一次导入更小的块,fx 1K行。 秒表计时看起来像这样:
- Count:100 |平均分:36
- 计数:200 |平均分:67
- 计数:300 |平均分:106
- 计数:400 |平均分:145
- 计数:500 |平均分:183
- 计数:600 |平均分:222
- 计数:700 |平均分:258
- 计数:800 |平均分:299
- 计数:900 |平均分:344
- 计数:1000 |平均毫秒:376
当用1K行的新块重新启动应用程序时,时间是相似的。
导入数据的格式如下:
public class ImportData
{
public int Id { get; set; }
public int TaxpayerId { get; set; }
public string CustomerName { get; set; }
public string Email { get; set; }
public string PhoneNumber { get;set; }
}
我的数据模型的一个简单的例子是这样的:
public class Channel
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Permission
{
public Guid Id { get; set; }
public Channel Channel { get; set; }
public string Recipient { get; set; }
}
public class Taxpayer
{
public Guid Id { get; set; }
public int TaxpayerId { get; set; }
public string Name { get; set; }
public List<Permission> Permissions { get; set; }
}
我的导入方法是这样的:
public void Import()
{
Stopwatch stopwatch = new Stopwatch();
//Get import data
List<ImportData> importDataList = _dal.GetImportData();
stopwatch.Start();
for (int i = 0; i < importDataList.Count; i++)
{
ImportData importData = importDataList[i];
Taxpayer taxpayer = new Taxpayer()
{
Name = importData.CustomerName,
TaxpayerId = importData.TaxpayerId,
Permissions = new List<Permission>()
};
//Does not call SaveChanges on the context
CreateTaxpayer(taxpayer, false);
//Create permissions
if (!string.IsNullOrWhiteSpace(importData.Email))
{
//Does not call SaveChanges on the context
CreatePermission(_channelIdEmail, importData.Email, taxpayer, PermissionLogType.PermissionRequestAccepted);
}
if (!string.IsNullOrWhiteSpace(importData.PhoneNumber))
{
//Does not call SaveChanges on the context
CreatePermission(_channelIdPhoneCall, importData.PhoneNumber, taxpayer, PermissionLogType.PermissionRequestAccepted);
//Does not call SaveChanges on the context
CreatePermission(_channelIdSms, importData.PhoneNumber, taxpayer, PermissionLogType.PermissionRequestAccepted);
}
if ((i + 1) % 100 == 0)
{
Console.WriteLine("Count: " + (i + 1) + " | Avg ms: " + stopwatch.ElapsedMilliseconds/100);
stopwatch.Restart();
}
}
_dal.SaveChanges();
}
我试过以下内容:
- 减少调用到的SaveChanges数量(只叫一次在结尾)
- 实现多线程(没有运气) - 它似乎并没有齐头并进与实体框架
我这里没有想法。你们有任何建议来解决这个性能问题吗?
请创建[MCVE。你显示的代码没有明显的问题。我会怀疑你做了一个Linq(无论是实体还是对象)查询某处,随着你添加项目到一个集合逐渐变慢。 – CodeCaster
*不要*使用ORM。使用SqlBulkCopy。 ORM不适用于批量操作,就像使用镊子移动整车的石块。您最终将跟踪*所有*记录,为每个*插入发送单独的INSERT请求。您*可以*禁用更改跟踪并添加一个扩展,以将批处理添加到EF,以便多个请求一起发送,但是通过SqlBulkCopy使用EF仍然没有任何收获。 –
[SqlBulkCopy和实体框架]的可能重复(http://stackoverflow.com/questions/2553545/sqlbulkcopy-and-entity-framework) –