批量操作可显著提升Entity Framework的性能

2014 年 12 月 11 日

当数据库管理员考虑高性能数据加载时,他们会考虑批量操作,这明显是 Entity Framework 不具备的功能。但也不一定就是如此。近日,我们采访了 ZZZ 项目的 Jonathan Magnan,谈了他们新提供的功能。

InfoQ:开发人员已经可以告诉 Entity Framework 将批量记录同时上传。那么为什么还需要批量操作呢?

Jonathan Magnan:很简单,为了获得巨大的性能。

想象一下,要求某人给你一本书,一次一页(Entity Framework),而不是给你整本书(批量操作)。一种技术明显比另一种技术更快:批量操作的性能要远远超过 Entity Framework。

ZZZ 项目通过 Entity Framework 扩展库提供两种批量操作。与 Entity Framework 的 SaveChanges 方法相比,它们极大地提供了性能。

BulkSaveChanges

第一种方式是我们的主要功能,正如字面上的意思,BulkSaveChanges 方法升级了 SaveChanges 方法。当有成千上万个实体时,它的保存速度预计快 10 到 15 倍。该方法支持各种关联和实体类型(TPC、TPH 和 TPT)。

复制代码
using (var ctx = new DbContextEntities())
{
//…对 DbContext 做任何修改…
ctx.BulkSaveChanges();
}

第二种方式是批量操作方法(BulkDelete、BulkInsert、BulkUpdate 和 BulkMerge)。它们对性能的提升更大,而且允许自定义许多设置,比如使用什么主键?

复制代码
using (var ctx = new DbContextEntities())
{
//…对 DbContext 做任何修改…
// 使用 Entity Framework 设置
ctx.BulkUpdate(list);
// 或者自定义设置
ctx.BulkUpdate (list,
operation=>operation.ColumnPrimaryKeyExpression=column=>column.ID);
}

InfoQ:在底层的 SQL 方面,批量操作与普通的 Entity Framework 操作有何不同?

Jonathan:Entity Framework 每保存一条记录就产生一次数据库访问。如果有 1000 个实体要更新,就需要访问数据库 1000 次,每次执行一条更新语句,整个过程可能需要几秒钟。另一方面,使用 Entity Framework 扩展库,一眨眼功夫就能完成。

我们可以像下面这样还原 SQL Server 的标准工作流程:

  • 在 SQL Server 中创建一张临时表;
  • 使用.NET SqlBulkCopy 将数据批量插入临时表;
  • 在临时表和目标表之间执行一条 SQL 语句;
  • 从 SQL Server 删除临时表。

数据库访问次数明显减少。

InfoQ:你们针对 Entity Framework 做过基准测试比较普通操作和批量操作码?

Jonathan:基准测试显示了四舍五入后的数值,因为已经相当明显,批量操作总是一种比做多次操作更快的方式。

Nb.Entities

SaveChanges

BulkSaveChanges

BulkOperations

1,000

1,000ms

90ms

70ms

2,000

2,000ms

150ms

110ms

5,000

5,000ms

350ms

220ms

在记录数以百万计的场景中,批量操作是唯一可行的方案。与 Entity Framework 相比,其性能可以为开发人员节省数小时甚至几天的时间。

Nb. Entities

BulkSaveChanges

BulkOperations

100,000

7s

4.5s

1,000,000

75s

45s

10,000,000

750s

450s

在真实环境的场景中,随着列数、索引、触发器和服务器负载的增加,Entity Framework 与批量操作之间的性能差距甚至更大。

此外,速度不是唯一重要的因素,向 SQL Server 服务器发起成千上万次访问从来都不是一个好的解决方案。即使你的应用程序受此低性能的影响不大,但这可能会影响其它应用程序的性能。

InfoQ:批量操作有什么缺点?比如,要使它有效,有最小行数要求吗?

Jonathan:缺点是需要额外的启动加载。同 Entity Framework 一样,在第一次基于实体及其关系使用它时,需要收集并缓存信息。

甚至于只有一行数据时,它都可以同 Entity Framework 效果一样。它会根据需要保存的行数改变保存策略。

InfoQ:你们计划在 CodePlex 上将 Entity Framework 批量操作贡献给 Entity Framework 主干吗?

Jonathan:很遗憾,不会。SqlBulkCopy 已经创建十年多了,.NET Framework 仍然没有支持批量删除、更新和合并。我们提供了这些方法,我们的网站上有更多的功能。

InfoQ:您对微软将 Entity Framework 移交给.NET 基金会有什么看法?

Jonathan: 我认为,微软此举意义重大,因为开源社区发展很快。作为一名程序员,看看微软项目的演进以及微软的开发人员如何编码总是很有趣的。这使经常使用 Entity Framework 的开发人员可以很简单地分享代码、建议和思路。这是我们希望的一次创新性转变, 一定会对微软和.NET 社区产生积极的影响。

查看英文原文:**** Dramatically Improve Entity Framework Performance with Bulk Operations


感谢孙镜涛对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014 年 12 月 11 日 02:4311181
用户头像

发布了 1008 篇内容, 共 307.0 次阅读, 收获喜欢 272 次。

关注

评论

发布
暂无评论
发现更多内容

某二手交易平台大数据平台从 0 到 1 演进与实践

奈学教育

奈学教你五分钟学会分布式事务

奈学教育

分布式系统

日志过滤

HU

Pycharm社区版安装教程(永久免费,随时升级)

早睡蟒

推荐几款有意思的小众App(06.06)

静陌

程序员可迁移技能的培养

码闻强

程序员 程序员素养 程序员成长

我体验了一把自由职业,比 996 苦多了...

非著名程序员

创业 程序员 自由职业 创业心态

架构师应该具备哪些思维模型?

奈学教育

架构师

Go: Go 调度器的任务窃取(Work-Stealing)

陈思敏捷

go golang 源码分析 原理 队列

单例模式详解

章小传

Java 单例模式

[kube 022] 混沌测试框架-Litmus

zbyufei

Kubernetes 云原生 混沌工程 Litmus litmuschaos

ARTS week3

丽子

Spring 源码学习 - 单例bean的实例化过程

公众号:好奇心森林

ARTS Week2

时之虫

ARTS 打卡计划

彻底搞懂 etcd 系列文章(一):初识 etcd

aoho

架构 云原生 etcd

ES2020 new features / ES11

xgqfrms

ES2020 new features ES11 ES2020

ARTS - Week Three

shepherd

开源 互联网 算法

彻底搞懂 etcd 系列文章(三):etcd 集群运维部署

aoho

架构 云原生 etcd

Trie 字典树

12583

LeetCode Trie

JDK 8,该离开的时候,请别留恋!

范学雷

Java 架构 编程语言 Java 25 周年

ARTS|Week 02:体会刷算法题的快乐,同时开启Ubuntu 20.04备用系统

MiracleWong

算法 ARTS 打卡计划

听说用 Lombok 可以早点下班?

武培轩

Java 程序员 工具 后端 IDEA

江湖事儿 | 技术人如何做好晋升准备

哈利迪

android 职业成长

ARTS|Week 2 PlantUML 的学习和分享

Puran

LeetCode arts PlantUML

像运营公司一样去做产品

胖鱼2号

创业 产品 产品经理 企业

Spark学习笔记一之为什么Spark这么牛逼

Shockang

大数据 spark

GitLab CI/CD

xgqfrms

重装Oracle11g

阡陌r

oracle 踩坑 oracle重装

原创 | TDD工具集:JUnit、AssertJ和Mockito (十九)编写测试-依赖注入\测试接口\重复测试

编程道与术

Java 编程 TDD 单元测试 JUnit

C/C++:const常量真的可以用指针修改吗

韩小非

c c++ 指针 常量 编译器优化

缓存一致性协议的工作方式

HackMSF

缓存 并发

批量操作可显著提升Entity Framework的性能-InfoQ