I'm seeing some really strange perf related to a very simple query using Entity Framework Code-First with .NET framework version 4. The LINQ2Entities query looks like this:
context.MyTables.Where(m => m.SomeStringProp == stringVar);
This takes over 3000 milliseconds to execute. The generated SQL looks very simple:
SELECT [Extent1].[ID], [Extent1].[SomeStringProp], [Extent1].[SomeOtherProp], ... FROM [MyTable] as [Extent1] WHERE [Extent1].[SomeStringProp] = '1234567890'
This query runs almost instantaneously when run through Management Studio. When I change the C# code to use the SqlQuery function, it runs in 5-10 milliseconds:
context.MyTables.SqlQuery("SELECT [Extent1].[ID] ... WHERE [Extent1].[SomeStringProp] = @param", stringVar);
So, exact same SQL, the resulting entities are change-tracked in both cases, but wild perf difference between the two. What gives?
Entity Framework loads very slowly the first time because the first query EF compiles the model. If you are using EF 6.2, you can use a Model Cache which loads a prebuilt edmx when using code first; instead, EF generates it on startup.
EF Core 6.0 performance is now 70% faster on the industry-standard TechEmpower Fortunes benchmark, compared to 5.0. This is the full-stack perf improvement, including improvements in the benchmark code, the . NET runtime, etc. EF Core 6.0 itself is 31% faster executing queries.
Found it. It turns out it's an issue of SQL data types. The SomeStringProp
column in the database was a varchar, but EF assumes that .NET string types are nvarchars. The resulting translation process during the query for the DB to do the comparison is what takes a long time. I think EF Prof was leading me astray a bit here, a more accurate representation of the query being run would be the following:
SELECT [Extent1].[ID], [Extent1].[SomeStringProp], [Extent1].[SomeOtherProp], ... FROM [MyTable] as [Extent1] WHERE [Extent1].[SomeStringProp] = N'1234567890'
So the resulting fix is to annotate the code-first model, indicating the correct SQL data type:
public class MyTable { ... [Column(TypeName="varchar")] public string SomeStringProp { get; set; } ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With