gpt4 book ai didi

c# - Entity Framework - 快速插入/更新数百万条记录

转载 作者:行者123 更新时间:2023-12-05 05:00:36 25 4
gpt4 key购买 nike

我需要向 MySQL 数据库中插入 190 万条新记录。要使用它,我使用的是 C# Entity Framework,但这个过程似乎非常慢。按照目前的速度,处理这些记录需要几天时间。

我做错了什么,我该如何加快速度?

在数据库中,我有 2 个表:哈希和类别。每个散列应该是唯一的,并且可以有多个类别,每个散列只有 1 个类别处于事件状态。

我需要遵循的过程是首先检查散列是否存在。如果是,那么我需要找到当前类别,将其停用并添加新类别。

问题是我的 try{ } 语句大约需要 150 毫秒,而执行 SaveChanges() 的 block 大约需要 15-30 秒。因此,以这种方式处理 1.9M 记录将需要几天时间。

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");
}

最佳答案

这永远不会是最快的方法,但至少您需要避免在更改跟踪器中累积所有实体。每次 SaveChanges() 运行后的 EG

    foreach (var e in db.ChangeTracker.Entries())
{
e.State = EntityState.Detached;
}

关于c# - Entity Framework - 快速插入/更新数百万条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63038838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com