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:
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; }
...
}
I had this problem as well. It turns out the culprit in my case was SQL-Server parameter sniffing.
The first clue that my problem was in fact due to parameter sniffing was that running the query with "set arithabort off" or "set arithabort on" yielded drastically different execution times in Management Studio. This is because ADO.NET by default uses "set arithabort off" and Management Studio defaults to "set arithabort on". The query plan cache keeps different plans depending on this parameter.
I disabled query plan caching for the query, with the solution you can find here.
The reason of slowing down my queries made in EF was comparing not nullable scalars with nullable scalars:
long? userId = 10; // nullable scalar
db.Table<Document>().Where(x => x.User.Id == userId).ToList() // or userId.Value
^^^^^^^^^ ^^^^^^
Type: long Type: long?
That query took 35 seconds. But a tiny refactoring like that:
long? userId = 10;
long userIdValue = userId.Value; // I've done that only for the presentation pursposes
db.Table<Document>().Where(x => x.User.Id == userIdValue).ToList()
^^^^^^^^^ ^^^^^^^^^^^
Type: long Type: long
gives incredible results. It took only 50ms to complete. It's possible that it is a bug in EF.
I also came across this with a complex ef query. One fix for me which reduced a 6 second ef query to the sub second sql query it generated was to turn off lazy loading.
To find this setting (ef 6) go to the .edmx file and look in the Properties -> Code generation -> Lazy Loading Enabled. Set to false.
Massive improvement in performance for me.
If you're using the fluent mapping, you can use IsUnicode(false)
as part of the configuration to get the same effect -
http://msdn.microsoft.com/en-us/data/jj591617.aspx#1.9
http://msdn.microsoft.com/en-us/library/gg696416%28v=vs.103%29.aspx
I had the same problem (the query is fast when executed from SQL manager) but when executed from EF the timeout expires.
Turns out that the entity (which was was created from the view) had wrong entity keys. So the entity had duplicate rows with the same keys, and I guess it had to do grouping on the background.