Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework query slow, but same SQL in SqlQuery is fast

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?

like image 420
Brian Sullivan Avatar asked Apr 02 '13 15:04

Brian Sullivan


People also ask

Why is Entity Framework so slow?

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.

Is EF core fast?

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.


1 Answers

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; }      ... } 
like image 200
Brian Sullivan Avatar answered Sep 21 '22 19:09

Brian Sullivan