entity framework查询速度慢,但SqlQuery中的相同的SQL很快

我看到一些非常简单的查询使用entity framework代码优先与.NET框架版本4一些非常奇怪的性能。LINQ2Entities查询如下所示:

context.MyTables.Where(m => m.SomeStringProp == stringVar); 

这需要超过3000毫秒的时间来执行。 生成的SQL看起来很简单:

  SELECT [Extent1].[ID], [Extent1].[SomeStringProp], [Extent1].[SomeOtherProp], ... FROM [MyTable] as [Extent1] WHERE [Extent1].[SomeStringProp] = '1234567890' 

此查询在运行Management Studio时几乎可以即时运行。 当我更改C#代码以使用SqlQuery函数时,它运行5-10毫秒:

  context.MyTables.SqlQuery("SELECT [Extent1].[ID] ... WHERE [Extent1].[SomeStringProp] = @param", stringVar); 

因此,完全相同的SQL,所得到的实体在两种情况下都被更改跟踪,但是两者之间的性能差异很大。 是什么赋予了?

find了。 事实certificate,这是一个SQL数据types的问题。 数据库中的SomeStringProp列是一个varchar,但EF假定.NETstringtypes是nvarchar。 在查询数据库进行比较过程中产生的翻译过程需要很长时间。 我认为EF Prof在这里让我误入歧途,对查询运行的更精确的描述如下:

  SELECT [Extent1].[ID], [Extent1].[SomeStringProp], [Extent1].[SomeOtherProp], ... FROM [MyTable] as [Extent1] WHERE [Extent1].[SomeStringProp] = N'1234567890' 

所以最终的解决scheme是注释代码优先模型,指出正确的SQL数据types:

 public class MyTable { ... [Column(TypeName="varchar")] public string SomeStringProp { get; set; } ... } 

减慢我在EF中查询的原因是比较不可空标量和可空标量:

 long? userId = 10; // nullable scalar db.Table<Document>().Where(x => x.User.Id == userId).ToList() // or userId.Value ^^^^^^^^^ ^^^^^^ Type: long Type: long? 

该查询耗时35秒。 但是像这样的一个小的重构:

 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 

提供了令人难以置信 它只用了50ms就完成了。 这可能是EF中的一个错误。

如果您使用stream畅的映射,您可以使用IsUnicode(false)作为configuration的一部分,以获得相同的效果 –

http://msdn.microsoft.com/en-us/data/jj591617.aspx#1.9

http://msdn.microsoft.com/en-us/library/gg696416%28v=vs.103%29.aspx

我有同样的问题(从SQLpipe理器执行查询是快速的),但从EF执行超时过期。

原来那个实体(它是从视图中创build的)具有错误的实体键。 所以实体有相同的键重复的行,我想它不得不在背景上进行分组。

我也遇到了一个复杂的查询。 一个修复程序,减less了6秒的查询,以生成它的第二个SQL查询是closures延迟加载。

要find此设置(例如6),请转到.edmx文件并查看属性 – >代码生成 – >延迟加载启用。 设置为false。

对我来说,性能的大幅提高。

您可以使用以下技巧来加快查询速度 –

  1. 在获取上下文之前将ctx.Configuration.ProxyCreationEnabled设置为false
  2. 此外, .Select(c => new {c.someproperty})将只提取所需的数据,而不是整个一堆。

让我知道这是否有帮助。