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) –