Entity Framework数据插入性能追踪

简介: 写在开头:本文的评论者大多认为我这个测试不对,但是哪里不对没有谁给出一个明确的回复;对于若干纯粹谩骂的评论(似乎我说EF性能低==侮辱了他全家),我已删除。我的目的就是插入7千条数据到数据库中,得出的结论是在数据Add到上下文这个阶段比较耗时,如果有能绕过这个过程的方法,或者改进的建议,请提出,否则我不认为EF在这个场景中性能低下的结论是错误的! 为了不“激怒”更多人,标题都改了好几次。

写在开头:本文的评论者大多认为我这个测试不对,但是哪里不对没有谁给出一个明确的回复;对于若干纯粹谩骂的评论(似乎我说EF性能低==侮辱了他全家),我已删除。我的目的就是插入7千条数据到数据库中,得出的结论是在数据Add到上下文这个阶段比较耗时,如果有能绕过这个过程的方法,或者改进的建议,请提出,否则我不认为EF在这个场景中性能低下的结论是错误的!

为了不“激怒”更多人,标题都改了好几次。当时写这篇文章并不是为了证明什么,纯粹是我在运行某项目的过程中“发现”了EF的某个瓶颈,遍寻解决方案未果,所以记录下来。唉,怪只怪我太单纯了……解决方法在文章最后。

另外关于在SaveChanges()时候会将生成的SQL语句一次性提交到数据库的言论也可以消了,后面有部分评论持这个观点,首先我一再强调瓶颈不在数据库交互阶段;为了避免类似无意义的评论反复出现,麻烦在吐槽之前用Profiler跟踪一下。

早就听说EF的性能不咋地,没想到真的不咋地,而且还不是一般的不咋地(一句玩笑话引来一群人口诛笔伐,不明真相的博主表示很淡定)。有图有真相,已经在项目中应用了EF的朋友慎入!

1、.NET4.0,EF4.4

 1 public void ExecRealTimeRun(List<RealTimeStocks> realTimeData)
 2 {
 3     using (var context = new StockDataEntities())
 4     {
 5         context.Database.ExecuteSqlCommand("delete from RealTimeStocks");
 6 
 7         var now1 = DateTime.Now.TimeOfDay;
 8         Console.WriteLine(string.Format("{0}开始将数据Add到上下文中,数据量:{1}", now1, realTimeData.Count));
 9         foreach (var data in realTimeData)
10         {
11             context.RealTimeStocks.Add(data);
12         }
13 
14         var now2 = DateTime.Now.TimeOfDay;
15         Console.WriteLine(string.Format("{0}数据Added完毕,开始执行Insert操作,耗时{1}", now2, now2 - now1));
16         try
17         {
18             context.SaveChanges();
19         }
20         catch (DbEntityValidationException dbEx)
21         { }
22         catch
23         { }
24 
25         var now3 = DateTime.Now.TimeOfDay;
26         Console.WriteLine(string.Format("{0}Insert完毕,耗时{1}", now3, now3 - now2));
27     }
28 }

很简单,木有多余逻辑,结果:

插入7K多数据,超过1分钟。反复测了几次,结果相差不大,假如将SaveChanges操作包裹在TransactionScope中(纯粹为了测试,看是不是更耗时),结果没什么变化。

2、.NET4.5,EF4.4

听说只要升级到.NET4.5,EF就会有性能上的提升,因为EF用到了.NET框架的某些类库,随着这些类库的升级,EF也提高了性能。so,干巴爹。结果:

(这图可以不用贴,因为和上图没什么两样)

3、.NET4.5,EF5.0

微软跟我说5.0有67%的性能提升(有人说只是提高了查询性能,这里侧重调侃),我想这么大公司会乱说?于是卸载了4.4,安装了5.0(貌似NuGet里,会根据你的.NET版本安装相应版本的EF;但是你.NET升级后,EF不会跟着升级,也不能直接更新)。重新启动测试,结果:

(这图可以不用贴,因为和上图没什么两样)

4、其实么,关键不是在数据库插入阶段,而是在代码层的Add阶段,so,我并不认为和ADO.NET相比较有什么意义,因为ADO.NET没有上下文,而低效点就是Add到上下文的过程(博主在这里明确表示,以下代码是为了比较SaveChanges方法和ADO.NET的执行效率,而非整个插入阶段的效率)有朋友评论说我Add的方式错了,不知道应该怎么写,请教。

无论如何,贴代码吧:

 1 public void ExecRealTimeRunByADO(List<RealTimeStocks> realTimeData)
 2 {
 3     string insertText = @"insert [dbo].[RealTimeStocks]([Hqgpdm], [Hqzrsp], [Hqjrkp], [Hqzjcj], [Hqcjsl], [Hqdqcjsl],
 4 [Hqcjje], [Hqdqcjje], [Hqcjbs], [Hqzgcj], [Hqzdcj], [Hqsyl1], [Hqsyl2], [Hqjgsd1], [Hqjgsd2], [Hqhycc], [Hqsjw5], [Hqssl5], 
 5 [Hqsjw4], [Hqssl4], [Hqsjw3], [Hqssl3], [Hqsjw2], [Hqssl2], [Hqsjw1], [Hqssl1], [Hqbjw1], [Hqbsl1], [Hqbjw2], [Hqbsl2], 
 6 [Hqbjw3], [Hqbsl3], [Hqbjw4], [Hqbsl4], [Hqbjw5], [Hqbsl5], [HQTime], [UpdateTime], [ExponentRiseDown], [RiseDownPercent], 
 7 [ExponentSwing], [TimeID], [RiseNum], [DownNum], [EqualNum], [DataSource], [IsDeleted], [AddTime], [SMGUID])
 8 values ('{0}', {1}, {2}, {3}, {4}, null, {5}, null, null, {6}, {7}, {8}, null, {9}, {10}, null, {11}, {12}, {13}, {14}, {15}, 
 9 {16}, {17}, {18}, null, {19}, null, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, '{29}', '{30}', {31}, {32}, {33}, {34},
10 {35}, {36}, {37}, null, {38}, '{39}', '{40}')";
11     using (var context = new StockDataEntities())
12     {
13         context.Database.ExecuteSqlCommand("delete from RealTimeStocks");
14 
15         var now2 = DateTime.Now.TimeOfDay;
16         Console.WriteLine(string.Format("{0}开始执行Insert操作", now2));
17         using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TimeSpan(0, 2, 0)))
18         {
19             try
20             {
21                 foreach (var data in realTimeData)
22                 {
23                     string cmd = string.Format(insertText, data.Hqgpdm, data.Hqzrsp, data.Hqjrkp, data.Hqzjcj, data.Hqcjsl,
24 data.Hqcjje, data.Hqzgcj, data.Hqzdcj, data.Hqsyl1, data.Hqjgsd1, data.Hqjgsd2, data.Hqsjw5, data.Hqssl5,
25 data.Hqsjw4, data.Hqssl4, data.Hqsjw3, data.Hqssl3, data.Hqsjw2, data.Hqssl2, data.Hqssl1, data.Hqbsl1, data.Hqbjw2, data.Hqbsl2,
26 data.Hqbjw3, data.Hqbsl3, data.Hqbjw4, data.Hqbsl4, data.Hqbjw5, data.Hqbsl5, data.HQTime, data.UpdateTime, data.ExponentRiseDown, data.RiseDownPercent,
27 data.ExponentSwing, data.TimeID, data.RiseNum, data.DownNum, data.EqualNum, data.IsDeleted ? 1 : 0, data.AddTime, data.SMGUID);
28                     context.Database.ExecuteSqlCommand(cmd);
29                 }
30                 scope.Complete();
31             }
32             catch
33             {
34                 Console.WriteLine("出错");
35                 return;
36             }
37 
38             var now3 = DateTime.Now.TimeOfDay;
39             Console.WriteLine(string.Format("{0}Insert完毕,耗时{1}", now3, now3 - now2));
40         }
41     }
42 }

Insert语句我是直接拷贝EF动态生成的语句,稍微修改了下。使用的虽然不是正宗的ADO.NET,但是也差不多,你别跟我说EF的ExecuteSqlCommand用的是另一套东西。

结果:

不言自明(看来还有些人不明白,博主想说:SaveChanges并没有多少性能损失)。

结论:坐等10.0版本!or context.Configuration.AutoDetectChangesEnabled = false!(thx to eflay && flytothemoon)

转载请注明本文出处:http://www.cnblogs.com/newton/archive/2013/06/06/3120497.html

目录
相关文章
|
4月前
|
SQL 数据处理 数据库
提升数据处理效率:深入探讨Entity Framework Core中的批量插入与更新操作及其优缺点
【8月更文挑战第31天】在软件开发中,批量插入和更新数据是常见需求。Entity Framework Core 提供了批处理功能,如 `AddRange` 和原生 SQL 更新,以提高效率。本文通过对比这两种方法,详细探讨它们的优缺点及适用场景。
126 0
|
4月前
|
存储 开发框架 .NET
提升数据处理效率:深入探索Entity Framework Core中的LINQ查询技巧与最佳实践
【8月更文挑战第31天】在现代 .NET 应用开发中,Entity Framework Core (EF Core) 是访问数据库的首选技术。本文通过在线商店案例,探讨 EF Core 中 LINQ 查询的最佳实践:使用 `Include` 加载相关数据,避免过早调用 `ToList()`,利用 `Select` 进行投影以优化性能,采用异步查询提升响应性,并考虑使用存储过程处理复杂查询。这些技巧有助于构建高效、可维护的数据访问层。
49 0
|
4月前
|
数据库
优化数据加载策略:深入探讨Entity Framework Core中的懒加载与显式加载技术及其适用场景
【8月更文挑战第31天】在 Entity Framework Core(EF Core)中,数据加载策略直接影响应用性能。本文将介绍懒加载(Lazy Loading)和显式加载(Eager Loading)的概念及适用场景。懒加载在访问导航属性时才加载关联实体,可优化性能,但可能引发多次数据库查询;显式加载则一次性加载所有关联实体,减少查询次数但增加单次查询的数据量。了解这些策略有助于开发高性能应用。
63 0
|
4月前
|
存储 运维 监控
Entity Framework Core 实现审计日志记录超棒!多种方法助你跟踪数据变化、监控操作,超实用!
【8月更文挑战第31天】在软件开发中,审计日志记录对于跟踪数据变化、监控用户操作及故障排查至关重要。Entity Framework Core (EF Core) 作为强大的对象关系映射框架,提供了多种实现审计日志记录的方法。例如,可以使用 EF Core 的拦截器在数据库操作前后执行自定义逻辑,记录操作类型、时间和执行用户等信息。此外,也可通过在实体类中添加审计属性(如 `CreatedBy`、`CreatedDate` 等),并在保存实体时更新这些属性来记录审计信息。这两种方法都能有效帮助我们追踪数据变更并满足合规性和安全性需求。
95 0
|
4月前
|
存储 SQL 测试技术
Entity Framework Core 中的存储过程超厉害!从定义到调用全攻略,提升性能与安全性!
【8月更文挑战第31天】在现代软件开发中,数据库操作效率至关重要。Entity Framework Core(EF Core)作为强大的对象关系映射(ORM)框架,支持存储过程,可提升数据库操作的性能、安全性和可维护性。本文详细介绍如何在 EF Core 中定义、配置及调用存储过程,并提供最佳实践建议,包括性能优化、安全性增强、代码可维护性提升以及参数化查询等。通过遵循这些指导原则,开发者能够充分利用存储过程的优势,显著提高应用程序质量和性能。附带完整示例代码,展示从定义实体类到调用存储过程的全过程。
236 0
|
4月前
|
安全 API 数据库
深入剖析Entity Framework Core中的查询过滤器:实现细粒度数据访问控制的全方位指南与实战代码示例
【8月更文挑战第31天】本文通过实例详细介绍了如何在Entity Framework Core中使用查询过滤器实现细粒度的数据访问控制。从创建基于EF Core的项目、配置数据库上下文到定义领域模型,逐步展示了查询过滤器的应用方法。通过具体代码示例,说明了如何设置全局过滤规则及在不同场景下关闭过滤器,以执行特定查询。此外,还探讨了如何结合用户身份验证和授权,实现基于角色的数据访问控制,确保数据安全性。通过这些步骤,帮助开发者构建高效且安全的数据库访问层。
42 0
|
6月前
|
存储 SQL BI
【Entity Framework】你知道如何处理无键实体吗
【Entity Framework】你知道如何处理无键实体吗
40 0
|
数据库
Entity Framework 并发冲突解决方案(上)
Entity Framework 并发冲突解决方案
208 0
Entity Framework 并发冲突解决方案(上)
|
存储 SQL 数据库
Entity Framework Core 捕获数据库变动
Entity Framework Core 捕获数据库变动
183 0
|
运维 安全 数据库
Entity Framework 并发冲突解决方案(下)
Entity Framework 并发冲突解决方案
172 0