• EF批量插入(转)


    原作者地址http://blog.csdn.net/zlts000/article/details/46385773

    之前做项目的时候,做出来的系统的性能不太好,在框架中使用了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(".");
                }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    用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));
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    好了现在运行,等待中…… 
    哎~~实在是没有耐心等待它运行完。 
    怎么办,减少数据量,先添加1000条:

    这里写图片描述

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

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

    这里写图片描述

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

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

    dbcontext.BulkInsert(customers);
    
    dbcontext.BulkSaveChanges();
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    直接上10W条:

    这里写图片描述

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

    那么20W呢?

    这里写图片描述

    20W条数据运行完,才花了6346毫秒,6.346秒的时间。比上面的方法添加1000条的数据用的时间差不多,看来EF自带的添加方法慢,是毋庸置疑的了。


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


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

    这里写图片描述

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

    这里写图片描述

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

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

  • 相关阅读:
    单例模式 异常抛出
    「分块系列」数列分块入门7 解题报告
    「分块系列」数列分块入门4 解题报告
    「分块系列」数列分块入门5 解题报告
    「分块系列」数列分块入门6 解题报告
    「分块系列」数列分块入门3 解题报告
    「分块系列」数列分块入门2 解题报告
    「分块系列」数列分块入门1 解题报告
    「黑科技」查错神器——对拍
    「洛谷P1196」「NOI2002」银河英雄传说 解题报告
  • 原文地址:https://www.cnblogs.com/xuyufeng/p/6612589.html
Copyright © 2020-2023  润新知