Database 实体框架-查询远程数据库时性能不佳
我为我们的新项目评估了几种.NET数据库访问技术,发现在使用实体框架查询远程数据库时存在性能不良的行为。实体框架比LinqToSql或SqlClient慢10倍。也许你能帮我解释一下或者解决这个问题 测试参数: 数据库:Database 实体框架-查询远程数据库时性能不佳,database,performance,entity-framework,Database,Performance,Entity Framework,我为我们的新项目评估了几种.NET数据库访问技术,发现在使用实体框架查询远程数据库时存在性能不良的行为。实体框架比LinqToSql或SqlClient慢10倍。也许你能帮我解释一下或者解决这个问题 测试参数: 数据库: SQL Server 2008企业版 一个表包含1000条记录 表结构: [dbo].[Master]( [Id] [int] IDENTITY(1,1) NOT NULL, [Value_Bit] [bit] NOT NULL, [
- SQL Server 2008企业版
- 一个表包含1000条记录
- 表结构:
[dbo].[Master]( [Id] [int] IDENTITY(1,1) NOT NULL, [Value_Bit] [bit] NOT NULL, [Value_Float] [float] NOT NULL, [Value_DateTime] [datetime2](7) NOT NULL, [Value_Uniqueidentifier] [uniqueidentifier] NOT NULL, [Value_NVarchar100] [nvarchar](100) NOT NULL, [Value_NVarchar1000] [nvarchar](1000) NOT NULL, [InsertDate] [datetime] NOT NULL, [UpdateDate] [datetime] NOT NULL, [Version] [timestamp] NOT NULL)
- .NET Framework 4和4.5
- 作为WinForms应用程序托管
- 实体框架5.0(RC)和4.3.1
- LinqToSQL
- SqlClient
- 三台硬件相似的不同计算机
- A和B在同一子网中(例如192.168.1.1和192.168.1.2)
- C与a和B位于不同的子网中(例如192.168.2.1)
select*from Master
。平均时间是1000次迭代的结果
测试场景1:
- 客户:A
- 服务器:A
- 实体框架:平均时间:17毫秒
- LinqToSQL:平均时间:20毫秒
- SqlClient:平均时间:15毫秒
- 客户:A
- 服务器:B
- 实体框架:平均时间:144毫秒
- LinqToSQL:平均时间:141毫秒
- SqlClient:平均时间:140毫秒
- 客户:A
- 服务器:C
- 实体框架:平均时间:2145毫秒
- LinqToSQL:平均时间:151毫秒
- SqlClient:平均时间:156毫秒
- 客户:B
- 服务器:C
- 实体框架:平均时间:2060毫秒
- LinqToSQL:平均时间:141毫秒
- SqlClient:平均时间:178毫秒
ToList
消耗的。如果深入调用堆栈,我会看到方法System.Data.SqlClient.SqlDataReader.GetString(Int32)
,最后是sninitivemethodwrapper.SNIReadSyncOverAsync(SafeHandle,IntPtr&,Int32)
,它一直在使用。LinqToSql也使用SqlClient,并且几乎拥有相同的调用堆栈,但执行时间是10倍
我不知道引擎盖下发生了什么。也许这和计算机名解析有关,但我可以通过IP地址和计算机名ping计算机C。有没有人能解释这一点,或者对如何加快执行速度提出建议
提前谢谢
Mathias问题分别大的时间间隔突然消失。我被告知管理员在网络上做了一些更改,因此我推断这与此有关,因为我在测试参数上没有做任何更改 不幸的是,我不知道他们发生了什么变化,我猜我永远也找不到答案。非常失望,因为我知道我不知道原因是什么
谢谢。如果没有看到您的代码,很难给出任何有根据的猜测,但是EF有一些典型的东西,您可以大致了解一下
- 通常,通过使用,您可以显著加快速度
- 在查看代码时,EF查询的延迟执行可能是一个不明显的陷阱
// Execution will be deferred:
IEnumerable<person> peopleList = objectContext.People.Where(item => item.ID > 100);
foreach (person somePerson in peopleList)
{
// do something here
}
//执行将被推迟:
IEnumerable peopleList=objectContext.People.Where(item=>item.ID>100);
foreach(人员列表中的人员)
{
//在这里做点什么
}
这段代码将对数据库进行多次往返,这可能会导致严重的性能问题。Du延迟执行和延迟加载这将导致人员列表中每个项目的代码再次查询数据库。根据通过网络传输的数据量,仅此一项就可能对性能造成严重损害
只需对集合调用ToList()方法,就可以减少此开销。这将在一次往返中获取所有结果对象:
// Execution will be deferred:
List<person> peopleList = objectContext.People.Where(item => item.ID > 100)
.ToList(); // Fetch objects NOW!
//执行将被推迟:
List peopleList=objectContext.People.Where(item=>item.ID>100)
.ToList();//现在取东西!
MSDN提供了一篇文章,其中包含一些建议:
提高绩效的策略
您可以提高整体性能
在实体框架中使用以下方法执行查询
战略
预生成视图
基于实体生成视图
模型是应用程序首次运行时的一项重要成本
执行查询。使用EdmGen.exe实用程序按以下方式预生成视图:
一个Visual Basic或C#代码文件,可在运行期间添加到项目中
设计。您也可以使用文本模板转换