0
@EDIT 我按照Fastest Way of Inserting in Entity Framework的步驟操作,結果變得更糟,所以它不是重複的。使用實體框架將大量行插入到數據庫中
我的目標是創建一個種子方法來填充LocalDb的其中一個表。該方法將添加182500行(模擬500個設備的年度活動數據)以供進一步測試。我可能想再運行幾次來更改設備的數量,因此會生成更多的行。這就是爲什麼我需要儘可能高效地插入行。
protected void SeedReportDataTable(int numberOfTerminals)
{
var rand = new Random();
var tidsList = new List<string>();
// generuj liste losowych numerow tid
for (int i = 0; i < numberOfTerminals; i++)
{
var randomTid = rand.Next(100000, 1000000).ToString(); // generuj 6-cyfrowy numer tid
while (tidsList.Contains(randomTid)) { randomTid = rand.Next(100000, 1000000).ToString(); } // elminuj powtorzenia
tidsList.Add(randomTid);
}
// dla kazdego z numerow tid generuj roczna historie aktywnosci
var recordsList = new BlockingCollection<ReportData>();
int year = Convert.ToInt32(DateTime.Now.Year);
Parallel.ForEach(tidsList, tid =>
{
// dla kazdego miesiaca
for (int month = 1; month <= 12; month++)
{
// dla kazdego dnia
for (int day = 1; day <= DateTime.DaysInMonth(year, month); day++)
{
var record = new ReportData
{
Tid = tid,
Active = Convert.ToBoolean(
rand.Next(0, 11)), // generuj losowy stan aktywnosci z prawdopodbienstwem 1/10 na bycie nieaktywnym
Date = new DateTime(year, month, day)
};
recordsList.Add(record);
}
}
});
// dodaj unikalne klucze glowne rekordom przed dodaniem do kontekstu bazy
var keyValue = 1;
foreach (var record in recordsList)
{
record.Id = keyValue++;
}
// podziel liste na czesci
int chunkSize = 1000;
for (int recordsSkipped = 0; recordsSkipped < recordsList.Count; recordsSkipped += chunkSize)
{
// wymieniaj kontekst
using (var db = new dbEntities())
{
db.Configuration.AutoDetectChangesEnabled = false;
db.Configuration.ValidateOnSaveEnabled = false;
// dodawaj do bazy po kawalku
db.ReportData.AddRange(recordsList.Skip(recordsSkipped).Take(chunkSize));
db.SaveChanges();
}
}
}
運行此代碼需要30分鐘才能完成。在此之前,我跑了一個版本結束:
using (var db = new dbEntities())
{
db.ReportData.AddRange(recordsList);
db.SaveChanges();
}
並花了15分鐘,這仍然比我預期的要慢。
爲什麼我的「改進」失敗?
我能做些什麼來使插入行更快?
[實體框架中插入的最快的方法]的可能的複製(https://stackoverflow.com/questions/5940225/fastest-way-of-inserting-in-entity-framework) –
你要在生產或Sql Server中使用LocalDB?如果你擔心生產性能,那麼你應該對Sql Server進行基準測試,如果這是在生產中運行的。 – Igor
這就是說使用EF爲許多記錄播種數據庫並不是最高性能的選擇。考慮使用Sql Bulk Insert,而不是在插入大量記錄(數百萬或更多)時性能至關重要。即使這樣你也應該檢查Sql Server的瓶頸(即索引更新和跨插入的統計更新也會減慢這樣的批處理工作)。 – Igor