我需要向MySQL数据库插入190万条新记录。我使用C# Entity Framework进行操作,但这个过程非常慢。按照当前速度,处理这些记录需要几天时间。
我做错了什么?如何加快速度?
我的数据库中有2个表:哈希(Hashes)和类别(Categories)。每个哈希应该是唯一的,可以有多个类别,每个哈希只能有一个活动类别。
我需要先检查哈希是否存在。如果存在,那么我需要找到当前的类别,将其停用并添加新的类别。
问题在于我的try{}语句大约需要150毫秒,执行SaveChanges()方法的块需要15-30秒左右。因此,以这种方式处理190万条记录需要数天时间。
我做错了什么?如何加快速度?
我的数据库中有2个表:哈希(Hashes)和类别(Categories)。每个哈希应该是唯一的,可以有多个类别,每个哈希只能有一个活动类别。
我需要先检查哈希是否存在。如果存在,那么我需要找到当前的类别,将其停用并添加新的类别。
问题在于我的try{}语句大约需要150毫秒,执行SaveChanges()方法的块需要15-30秒左右。因此,以这种方式处理190万条记录需要数天时间。
using (var reader = new StreamReader(File.OpenRead(filepath)))
using (MySQLContext db = new MySQLContext(options))
{
// Disable auto detect changes
db.ChangeTracker.AutoDetectChangesEnabled = false;
int loopCounter = 0;
string line;
// Load up the db tables in memory
var hashes = db.Hashes.Select(x => x).ToList();
var category = db.Categories.Select(a => a).ToList();
while ((line = reader.ReadLine()) != null)
{
var matches = Regex.Matches(line, "(?<MD5>[a-zA-Z0-9]+)(?<Category>[0-9])");
InputHashModel inputHash = new InputHashModel()
{
MD5 = matches[0].Groups["MD5"].Value,
Category = matches[0].Groups["Category"].Value
};
try
{
// Check if hash already exists
Hash hash = hashes.Where(h => h.MD5 == inputHash.MD5).FirstOrDefault();
// If hash doesn't exist - add it
if (hash == null)
hash = new Hash(inputHash.MD5);
else
{
// Check if category already exists
Category category = categories.Where(a => a.Active == true && a.HashId == hash.Id).FirstOrDefault();
// If it exists - deactivate it
if (category != null)
{
// If the same category already exists - proceed to next hash
if (category.Source == "ThisInput" && category.Category == inputHash.Category)
{
loopCounter++
continue;
}
category.Active = false;
category.DeactivatedTimestamp = DateTime.Now;
}
}
// Add new category
Category new_category = new Category() { Hash = hash, Source = "ThisInput", Category = inputHash.Category, Active = true);
db.Categories.Add(new_category);
// Save changes every 1000
if (loopCounter % 1000 == 0)
{
db.ChangeTracker.DetectChanges();
db.SaveChanges();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e);
}
loopCounter++;
}
db.ChangeTracker.AutoDetectChangesEnabled = true;
db.SaveChanges();
Console.WriteLine("Finished");
}
BulkUpdate()
函数,但它是第三方的。编辑:请看下面我的回答。 - ZeW