简体   繁体   中英

SQLite with Entity Framework Core is slow

Inserting a record to SQLite DB via Entity Framework Core in C# in .NET Core is extremely slow. It is 10 times slower than my expectation. Is there a magic to improve performance?

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 takes 10 seconds on my PC with SATA-SSD drive. Replacing to eNVM is not my option because I am writing an application for a sort of embedded system which has equivalent storage.

I tried using db.ChangeTracker.AutoDetectChangesEnabled = false; , or db.BulkSaveChanges(); (with Z.EntityFramework.Extensions.EFCore)

And they didn't help me.

My environment:

  • Visual Studio 2019 Version 16.11.2
  • .NET Core 3.1
  • C#
  • Microsoft.EntityFrameworkCore.Sqlite 5.0.11
  • Windows 10

Edit

The loop was a simulation of a process in the application. They are not single transaction. The loop is intended to simulate 1000 transactions. Therefore they cannot be in the same transaction.

It also cannot remove transaction. The transactions in the application is actually more complicate and can update two or more tables/records at the same time. It must be handled in a transaction. therefore removing transaction is not my option.

将连接命中数(在 for 循环内)限制到数据库可以解决线程中提到的问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM