[转]How to Improve Entity Framework Add Performance?
本文转自:http://entityframework.net/improve-ef-add-performance
When you overuse the Add() method for multiple entities, your application suffers from performance issues.
using (var ctx = new CustomerContext())
{
foreach(var line in lines)
{
var customer = new Customer();
// ...code...
ctx.Customers.Add(customer);
}
ctx.SaveChanges();
}
StackOverflow Related Questions
Answer
Is Entity Framework Add Really Slow?
In fact, the Add method is not slow at all. Adding an entity to a list cannot be that slow. It's the DetectChanges method invoked inside the Add method which is insanely slow!
Using the Add method in a loop is usually a poor practice which impacts your application performance severely when poorly used.
- USE AddRange over Add (Recommended)
- SET AutoDetectChanges to false
- SPLIT SaveChanges in multiple batches
Use AddRange over Add (Recommended)
When adding multiple entities, you should always use Entity Framework AddRange once with a list instead of calling multiple time the Add method.
Why?
- The Add method DetectChanges after every records added.
- The AddRange method DetectChanges after all records are added.
Performance Comparisons
| Operations | 100 Entities | 1,000 Entities | 10,000 Entities |
|---|---|---|---|
| Add | 15 ms | 1,050 ms | 105,000 ms |
| AddRange | 1 ms | 10 ms | 120 ms |
Note:
- *: SaveChanges time not included
- **: Entity with two relations
How?
- CREATE a list
- ADD entity to the list
- USE AddRange with the list
- SaveChanges
- Done!
using (var context = new EntityContext())
{
// 1. CREATE a list
List<Customer> list = new List<Customer>();
for(int i = 0; i < 2000; i++)
{
var customer = new Customer();
// ...code...
// 2. ADD entity to the list
list.Add(customer);
}
// 3. USE AddRange with the list
context.Customers.AddRange(list);
// 4. SaveChanges
ctx.SaveChanges();
// 5. Done!
}
SET AutoDetectChanges to false
When adding multiple entities, if you cannot use AddRange, set Entity Framework AutoDetectChanges to false
Why?
- The Add method DetectChanges after every records added.
By disabling AutoDetectChanges, the DetectChanges method will only be invoked when you do it.
Performance Comparisons
| Operations | 100 Entities | 1,000 Entities | 10,000 Entities |
|---|---|---|---|
| True (Default) | 15 ms | 1,050 ms | 105,000 ms |
| False | 1 ms | 14 ms | 180 ms |
Note:
- *: SaveChanges time not included
- **: Entity with two relations
How?
- SET AutoDetectChangesEnabled = false
- CALL DetectChanges before SaveChanges
- SaveChanges
- Done!
using (var context = new EntityContext())
{
// 1. SET AutoDetectChangesEnabled = false
context.Configuration.AutoDetectChangesEnabled = false;
List<Customer> list = new List<Customer>();
for(int i = 0; i < 2000; i++)
{
var customer = new Customer();
// ...code...
list.Add(customer);
}
context.Customers.AddRange(list);
// 2. CALL DetectChanges before SaveChanges
context.ChangeTracker.DetectChanges();
// 3. SaveChanges
context.SaveChanges();
// 4. Done!
}
SPLIT SaveChanges into multiple batches
This solution is not recommended. When adding multiple entities, split entities with a batch size in multiple different contexts.
Why?
More tracking entities your context contains, slower the DetectChanges method is! So by reducing the number of entities by context, you improve the performance.
Performance Comparisons
| Operations | 100 Entities | 1,000 Entities | 10,000 Entities |
|---|---|---|---|
| Unlimited | 15 ms | 1,050 ms | 105,000 ms |
| 10 | 3 ms | 40 ms | 350 ms |
| 100 | 15 ms | 125 ms | 1,200 ms |
| 1,000 | 15 ms | 1,050 ms | 10,200 ms |
Note:
- *: SaveChanges time not included
- **: Entity with two relations
How
- CREATE a batchSize variable
- CALL SaveChanges before creating a new batch
- CALL SaveChanges
- Done!
// 1. CREATE a batchSize variable
int batchSize = 400;
var context = new EntityContext();
for(int i = 0; i <= 2000; i++)
{
// 2. CALL SaveChanges before creating a new batch
if (i != 0 && i%batchSize == 0)
{
context.SaveChanges();
context = new EntityContext();
}
var customer = new Customer();
// ...code...
context.Customers.Add(customer);
}
// 3. CALL SaveChanges
context.SaveChanges();
// 4. Done!
[转]How to Improve Entity Framework Add Performance?的更多相关文章
- [2014-09-18]Entity Framework 6 预热、启动优化
好久没写博客了,终于憋出了一个大招,现在总结下. 虽然文章题目是针对EF的,但涉及的内容不仅仅是EF. 场景介绍 目前在做的一个项目,行业门户,项目部分站点按域名划分如下: user.xxx.com: ...
- Access MongoDB Data with Entity Framework 6
This article shows how to access MongoDB data using an Entity Framework code-first approach. Entity ...
- Entity Framework 6 预热、启动优化
虽然文章题目是针对EF的,但涉及的内容不仅仅是EF. 场景介绍 目前在做的一个项目,行业门户,项目部分站点按域名划分如下: user.xxx.com:用户登陆注册 owner.xxx.com:个人用户 ...
- Performance Considerations for Entity Framework 4, 5, and 6
Performance Considerations for Entity Framework 4, 5, and 6 https://msdn.microsoft.com/en-sg/data/hh ...
- [XAF] How to improve the application's performance
[自己的解决方案]数据量大时,可显著提升用户使用体验! 1.Root ListView 参考官方的E1554 点击导航菜单后首先跳出查询条件设置窗体进行设置 可设置查询方案或查询方案的查询条件,排序字 ...
- Why you should use async tasks in .NET 4.5 and Entity Framework 6
Improve response times and handle more users with parallel processing Building a web application usi ...
- Entity Framework与ADO.NET批量插入数据性能测试
Entity Framework是.NET平台下的一种简单易用的ORM框架,它既便于Domain Model和持久层的OO设计,也提高了代码的可维护性.但在使用中发现,有几类业务场景是EF不太擅长的, ...
- Code First :使用Entity. Framework编程(8) ----转发 收藏
第8章 Code First将走向哪里? So far, this book has covered all of the Code First components that reached the ...
- Code First :使用Entity. Framework编程(7) ----转发 收藏
第7章 高级概念 The Code First modeling functionality that you have seen so far should be enough to get you ...
随机推荐
- MySQL InnoDB配置并发线程( innodb_thread_concurrency)
http://www.ywnds.com/?p=9821 一.thread_concurrency 首先,最重要的一点,这个参数已经在最新版本的MySQL中被移除了,官方最新5.7版本的doc上面对t ...
- turtle库的学习笔记
(1)turtle使用pen来绘制图形 pendown() 放下画笔,移动到指定点后继续绘制 penup() 提起画笔,用于另起一个地方绘制时使用 pensize(width) 设置画笔线条 ...
- Python12/11--盒子的显隐/布局/z-index/流式布局思想
1.盒子的显隐 display:none 在页面中不占位,采用定位布局后,显示隐藏都不会影响其他标签,不需要用动画处理时,一般用这个 opacoity : 0 在页面中占位,采 ...
- 包含复杂函数的excel 并下载
POI 版本: <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</a ...
- Shell脚本-基本运算符
跟着RUNOOB网站的教程学习的笔记 shell和其他编程语言一样,支持多种运算符,包括: 算术运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符 expr是一款表达式计算公式,使用它能完成 ...
- ScriptOJ-flatten2#91
generator的使用 function *flatten2 (arr) { const result = [] function flatten(ar) { ar.map(iter => { ...
- .NET Core微服务之路:利用DotNetty实现一个简单的通信过程
上一篇我们已经全面的介绍过<基于gRPC服务发现与服务治理的方案>,我们先复习一下RPC的调用过程(笔者会在这一节的几篇文章中反复的强调这个过程调用方案),看下图
- 使用 Resharper 快速做适配器
如果需要做一个类的重写,需要重新写这个类的所有属性和函数,本文提供一个简单的方法让大家快速重写一个类的所有属性和函数. 在有 Resharper 之后,对一个比较长的类进行重构.例如有这个类 clas ...
- 笔记:BroadcastReceiver的运行过程
广播概述 广播用来在组件之间传递消息,可以是同进程或跨进程. 广播机制是基于发布订阅的事件驱动模型,使用上比Binder通信(跨进程接口回调)更低耦合.简单. ActivityManagerServi ...
- go连接mysql
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysq ...