EF大数据批量处理----BulkInsert


之前做项目的时候。做出来的系统的性能不太好,在框架中使用了EntityFramework,于是就在网上查资料,研究怎样提高EF的性能。
在这分享一篇博客 批量操作提升EntityFramework的性能
里面提供了一个扩展库Entity Framework扩展库,在这里面找到了一些比較好的方法。以下主要介绍当中的一个方法—-批量加入BulkInsert。


这些扩展方法在哪里找?


在VS中新建EF之后,右键解决方式下的引用, 选择管理NuGet程序包,搜索Z.EntityFramework.Extensions并安装。

这里写图片描写叙述

然后在类里面加入引用之后就能够直接点出来。


批量加入和EF本身自带的加入性能提高了多少?


以下咱们就用实例说话:
构造一个10W个studentinfo实例:

            '''定义要加入数据的条数'''
            int customerCount = 100000;

            '''定义一个实体集合'''
            List<studentInfo> customers = new List<studentInfo>();

            '''想集合中加入数据'''
            for (int i = 0; i < customerCount; i++)
            {
                studentInfo customer = new studentInfo()
                {
                    name = "2" + i,
                    sex = "2" + i,
                    studentID = "2" + i,
                    age = "2"
                };
                customers.Add(customer);

                Console.Write(".");
            }

用EF自带的加入方法将数据加入到数据库中,为了计算使用时间,加上StopWatch:

'''開始计时'''
Stopwatch watch = Stopwatch.StartNew();

using (EFTestEntities dbcontext = new EFTestEntities())
            {
                foreach (var entity in customers)
                {
                    dbcontext.studentInfoes.Add(entity);
                }
                dbcontext.SaveChanges();
            }

'''计时结束'''
watch.Stop();

'''输出时间'''
Console.WriteLine(string.Format("{0} customers are created, cost {1} milliseconds.", customerCount, watch.ElapsedMilliseconds));

好了如今执行。等待中……
哎~~实在是没有耐心等待它执行完。
怎么办,降低数据量,先加入1000条:

这里写图片描写叙述

还好,用时6157毫秒,6.157秒;

接着走,把数据量改为10000条:

这里写图片描写叙述

执行完了。共117096毫秒。117.096秒,将近两分钟。实在是没有耐心再測100000条的了,接下来直接測批量加入的方法。

将上面的加入到数据库中的代码换成以下的代码:

dbcontext.BulkInsert(customers);

dbcontext.BulkSaveChanges();

直接上10W条:

这里写图片描写叙述

执行完了,共3592毫秒,3.592秒,真快啊~~

那么20W呢?

这里写图片描写叙述

20W条数据执行完,才花了6346毫秒。6.346秒的时间。比上面的方法加入1000条的数据用的时间差点儿相同,看来EF自带的加入方法慢,是毋庸置疑的了。


为什么扩展方法用的时间这么少?


EF自带的方法,会添加与数据库的交互次数。一般地,EF的一个上下文在提交时会打开一个数据连接。然后把转换成的SQL语句一条一条的发到数据库端,然后去提交,以下的图片是我用SQL Server Profiler记录的和数据库交互的操作,这仅仅是一小部分,试想。假设你的数据量达到万级别(更不用说百万。千万数据了),那对数据库的压力是非常大的

这里写图片描写叙述

而扩展方法执行时与数据库的交互是这种:

这里写图片描写叙述

批量加入的方法是生成一条SQL语句,和数据库仅仅交互一次。那为什么图片中有多条Insert语句呢。当你使用BulkInsert时。假设数据达到4万之前。那在SQL的解释时,也是非常有压力的,有多情况下会超时,当然这与你的数据库server有关。但为了性能与安全。将Bulk操作变为分批提交,即将上W的数据进行分解。分用1W数据量提交一次,这样,对数据库的压力就小一些。

源码下载:EF扩展方法BulkInsert(批量加入)

posted @ 2017-07-02 20:06  brucemengbm  阅读(2004)  评论(0编辑  收藏  举报