-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance with SQLite and Microsoft.EntityFrameworkCore.Sqlite.Core and SQLitePCLRaw.bundle_e_sqlcipher #23099
Comments
We created a small .NET Core console app that demonstrates the performance. After further testing it appears that the Encryption is the culprit. With a non-encrypted database, the queries execute in about 20ms with the encryption enabled the same query takes over 600ms. Out of curiosity we tried it with the latest EF Core 5.0 RC2 and it is even slower at over 900ms. Is there any way to speed this up and keep the encryption? Any pragma settings that help, any encryption settings that help? We accepted the defaults for everything and made sure WAL was enabled. Packages used in the last round of tests: <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.0-rc.2.20475.6" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.0.4" /> Thank you in advance for any ideas or suggestions. |
We took the same example and dropped back to EF Core 2.2 and the queries, even with encryption, only take about 20ms, similar to the non-encrypted performance. I am now thinking this should be considered a bug. <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="SQLitePCLRaw.bundle_sqlcipher" Version="1.1.14" /> |
"We created a small .NET Core console app that demonstrates the performance." Can we see it? :-) |
@ericsink , thank you for the quick reply! |
ConsoleSqliteTest.zip |
@wjvii It appears that in the 2.1 repro, a single The 5.0 repro, on the other hand, results in the connection being opened and closed repeatedly because an open connection is no longer passed to DbContext. This causes poor perf since opening a connection to an encrypted SQLite database is very slow. I would recommend limiting the number of times the SQLite connection is opened in the 5.0 case by passing an open connection to the context, or by opening the connection explicitly before running EF queries and closing afterwards so that EF won't be opening and closing the connection for each query. (Keep in mind though that SqliteConnection, like all DbConnection implementations, is not thread-safe. 2.1 Logs:
5.0 logs:
|
@ajcvickers that is some excellent sleuthing. So when I new up a DbContext what is the recommended way to tell it I do not wish it to close the connection between uses? The way it was done for 2.1 was really done to handle the password via the Pragma which is now done in the connection string thanks to the new Microsoft.Data.Sqlite. |
@wjvii In general, if you open the connection, then EF will leave it open. So the way to get EF to not open/close the connection is to manually open the connection at the appropriate time (based on your application needs) and then manually close it after having EF do stuff. |
@ajcvickers that worked great. I just created the DbContext as db and then used db.Database.OpenConnection() and if I didn't close it performance is back where I expected it to be. One more question for you, that debug output is awesome, is there an article you can point me to on how-to setup to get that output from EF 3.1 and 5? Thank you again, this was a huge help! |
@wjvii I'm currently working on updated docs for logging--this PR is a good place to look until we get this merged live: dotnet/EntityFramework.Docs#2787 |
We are currently testing encrypted SQLite and we are experiencing slow performance (500 ms for commiting transaction) when inserting into database. dbug: 8/18/2022 08:20:39.382 CoreEventId.ValueGenerated[10808] (Microsoft.EntityFrameworkCore.ChangeTracking)
'TestDBContext' generated temporary value '-9223372036854774805' for the property 'DrawCardId.DrawCard'.
dbug: 8/18/2022 08:20:39.382 CoreEventId.StartedTracking[10806] (Microsoft.EntityFrameworkCore.ChangeTracking)
Context 'TestDBContext' started tracking 'DrawCard' entity with key '{DrawCardId: -9223372036854774805}'.
dbug: 8/18/2022 08:20:39.383 CoreEventId.SaveChangesStarting[10004] (Microsoft.EntityFrameworkCore.Update)
SaveChanges starting for 'TestDBContext'.
dbug: 8/18/2022 08:20:39.383 CoreEventId.DetectChangesStarting[10800] (Microsoft.EntityFrameworkCore.ChangeTracking)
DetectChanges starting for 'TestDBContext'.
dbug: 8/18/2022 08:20:39.383 CoreEventId.DetectChangesCompleted[10801] (Microsoft.EntityFrameworkCore.ChangeTracking)
DetectChanges completed for 'TestDBContext'.
dbug: 8/18/2022 08:20:39.384 RelationalEventId.ConnectionOpening[20000] (Microsoft.EntityFrameworkCore.Database.Connection)
Opening connection to database 'main' on server 'TestDatabase.db'.
dbug: 8/18/2022 08:20:39.384 RelationalEventId.ConnectionOpened[20001] (Microsoft.EntityFrameworkCore.Database.Connection)
Opened connection to database 'main' on server 'TestDatabase.db'.
dbug: 8/18/2022 08:20:39.384 RelationalEventId.TransactionStarting[20209] (Microsoft.EntityFrameworkCore.Database.Transaction)
Beginning transaction with isolation level 'Unspecified'.
dbug: 8/18/2022 08:20:39.385 RelationalEventId.TransactionStarted[20200] (Microsoft.EntityFrameworkCore.Database.Transaction)
Began transaction with isolation level 'Serializable'.
dbug: 8/18/2022 08:20:39.385 RelationalEventId.CommandCreating[20103] (Microsoft.EntityFrameworkCore.Database.Command)
Creating DbCommand for 'ExecuteReader'.
dbug: 8/18/2022 08:20:39.385 RelationalEventId.CommandCreated[20104] (Microsoft.EntityFrameworkCore.Database.Command)
Created DbCommand for 'ExecuteReader' (0ms).
dbug: 8/18/2022 08:20:39.386 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[@p0='1', @p1='52', @p2=NULL, @p3='2022-08-18T06:20:39.3822396Z' (DbType = DateTime), @p4='1', @p5='3', @p6='1'], CommandType='Text', CommandTimeout='30']
INSERT INTO "DrawCard" ("DrawId", "Card", "ChangeUser", "DrawDate", "Hand", "Index", "Status")
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);
SELECT "DrawCardId", "ChangeDate"
FROM "DrawCard"
WHERE changes() = 1 AND "rowid" = last_insert_rowid();
info: 8/18/2022 08:20:39.386 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
Executed DbCommand (1ms) [Parameters=[@p0='1', @p1='52', @p2=NULL, @p3='2022-08-18T06:20:39.3822396Z' (DbType = DateTime), @p4='1', @p5='3', @p6='1'], CommandType='Text', CommandTimeout='30']
INSERT INTO "DrawCard" ("DrawId", "Card", "ChangeUser", "DrawDate", "Hand", "Index", "Status")
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);
SELECT "DrawCardId", "ChangeDate"
FROM "DrawCard"
WHERE changes() = 1 AND "rowid" = last_insert_rowid();
dbug: 8/18/2022 08:20:39.387 CoreEventId.ForeignKeyChangeDetected[10803] (Microsoft.EntityFrameworkCore.ChangeTracking)
The foreign key property 'DrawCard.DrawCardId' was detected as changed from '-9223372036854774805' to '3' for entity with key '{DrawCardId: 3}'.
dbug: 8/18/2022 08:20:39.388 RelationalEventId.DataReaderDisposing[20300] (Microsoft.EntityFrameworkCore.Database.Command)
A data reader was disposed.
- dbug: 8/18/2022 08:20:39.388 RelationalEventId.TransactionCommitting[20210] (Microsoft.EntityFrameworkCore.Database.Transaction)
Committing transaction.
- dbug: 8/18/2022 08:20:39.856 RelationalEventId.TransactionCommitted[20202] (Microsoft.EntityFrameworkCore.Database.Transaction)
Committed transaction.
dbug: 8/18/2022 08:20:39.856 RelationalEventId.ConnectionClosing[20002] (Microsoft.EntityFrameworkCore.Database.Connection)
Closing connection to database 'main' on server 'TestDatabase.db'.
dbug: 8/18/2022 08:20:39.857 RelationalEventId.ConnectionClosed[20003] (Microsoft.EntityFrameworkCore.Database.Connection)
Closed connection to database 'main' on server 'TestDatabase.db'.
dbug: 8/18/2022 08:20:39.858 RelationalEventId.TransactionDisposed[20204] (Microsoft.EntityFrameworkCore.Database.Transaction)
Disposing transaction.
dbug: 8/18/2022 08:20:39.858 CoreEventId.StateChanged[10807] (Microsoft.EntityFrameworkCore.ChangeTracking)
The 'DrawCard' entity with key '{DrawCardId: 3}' tracked by 'TestDBContext' changed state from 'Added' to 'Unchanged'.
dbug: 8/18/2022 08:20:39.858 CoreEventId.SaveChangesCompleted[10005] (Microsoft.EntityFrameworkCore.Update)
SaveChanges completed for 'TestDBContext' with 1 entities written to the database. Include provider and version information |
@iplusMario If you believe this is an issue with EF Core or the ADO.NET driver, as opposed to with SQLite itself, then please open a new issue and attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate. |
Thank you for your answer. I opened new a issue https://github.com/dotnet/efcore/issues/28774. |
We recently updated an application from EF Core 2.1 to EF Core 3.1 and have noticed that the performance of our queries against SQLite has decreased significantly with simple single table queries taking considerably longer, often just under a full second. The same operations that used to take 7 seconds now take around 75 seconds. Most of these tables are simple with an Integer primary key. We have WAL enabled and during OnConfiguring have run PRAGMA synchronous = 'NORMAL'.
We are continuing to investigate but right now wondering if anyone else has run into something similar and if they found the cause.
Thank you in advance for any insight or suggestions.
Include provider and version information
EF Core version: 3.1.9 and SQLitePCLRaw.bundle_e_sqlcipher 2.0.4
Database provider: Microsoft.EntityFrameworkCore.Sqlite.Core
Target framework: (e.g. .NET Core 3.1)
Operating system: Windows 10 20H2
IDE: (e.g. Visual Studio 2019 16.8)
The text was updated successfully, but these errors were encountered: