带有 Entity Framework Core 的 SQLite 很慢
Posted
技术标签:
【中文标题】带有 Entity Framework Core 的 SQLite 很慢【英文标题】:SQLite with Entity Framework Core is slow 【发布时间】:2021-12-02 06:03:23 【问题描述】:在 .NET Core 中通过 C# 中的 Entity Framework Core 向 SQLite DB 插入记录非常慢。它比我的预期慢 10 倍。有没有提高性能的魔法?
public class MyRecord
[Key]
public int ID get; set;
public int Value get; set;
public class MyDatabase : DbContext
public DbSet<MyRecord> Records get; set;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
optionsBuilder.UseSqlite("Data source=mydb.db");
#if DEBUG
optionsBuilder.EnableSensitiveDataLogging(true);
#endif
public class MyDatabaseTests
public MyDatabaseTests()
var db = new MyDatabase();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
[TestMethod]
public void EntityFramework1000Transactions()
for (int i = 0; i < 1000; i++)
using var db = new MyDatabase();
var rec = new MyRecord
ID = i+1,
Value = 123456789
;
var tx = db.Database.BeginTransaction();
db.Records.Add(rec);
db.SaveChanges();
tx.Commit();
EntityFramework1000Transactions
在我的带有 SATA-SSD 驱动器的 PC 上需要 10 秒。替换为 eNVM 不是我的选择,因为我正在为一种具有等效存储的嵌入式系统编写应用程序。
我尝试使用db.ChangeTracker.AutoDetectChangesEnabled = false;
,或者
db.BulkSaveChanges();
(使用 Z.EntityFramework.Extensions.EFCore)
他们没有帮助我。
我的环境:
Visual Studio 2019 版本 16.11.2 .NET Core 3.1 C# Microsoft.EntityFrameworkCore.Sqlite 5.0.11 Windows 10编辑
循环是应用程序中进程的模拟。它们不是单一的交易。 该循环旨在模拟 1000 笔交易。因此它们不能在同一个交易中。
它也不能删除事务。应用程序中的事务实际上更复杂,可以同时更新两个或多个表/记录。它必须在事务中处理。因此删除交易不是我的选择。
【问题讨论】:
一次添加所有记录,而不是循环。此外,无论您为每次迭代构建MyDatabase
的任何原因,都没有必要这样做。我认为解决这两个问题将大大提高性能。
重用上下文,删除事务并批量保存,而不是每个单独的项目。这不是魔法,只是正确使用了 EF Core
因此,您可能必须生成线程,而不仅仅是同步循环。我不相信在实际应用程序中你有 1000 个线程来完成这样的任务。此外,您不必启动事务,如果 SaveChanges 无法在一个 SQL 语句中执行,它会在后台执行此操作。
谢谢斯维亚托斯拉夫。我们的设备很少有线程并且可以相互通信。每个线程都有状态机,并且必须对电源循环安全。我最初调用单个 SaveChanges,但我了解到 DbContext 在调用 ExecuteSqlRaw 时会混淆。我还了解到,即使只更新一条记录,创建事务总是比没有事务快。
很难说该怎么做。 EF 增加了额外的开销,但我认为在这种情况下并不重要。无论如何测试没有 EF,只是通过 SQLiteConnection 和事务的纯 SQL。并且 SQLite 可能不适合您的情况。
【参考方案1】:
限制对数据库的连接命中数(在for循环内)可以解决this线程中提到的问题。
【讨论】:
虽然 EF 在处理 DbContext 时处理 DbConnection,但 EF 核心保留 DbConnection。我还阅读了一篇文章,说应该为每个转换处理 DbContext。以上是关于带有 Entity Framework Core 的 SQLite 很慢的主要内容,如果未能解决你的问题,请参考以下文章
在 Entity Framework Core 中为 PostgreSQL 表的计算列设置公式
在 ASP.NET Core 中使用 Entity Framework 6
.NET Core 的 NUnit Entity Framework 集成测试依赖注入问题
Entity Framework Core Linq NULL 不起作用的地方