zoukankan      html  css  js  c++  java
  • ASP.Net杂谈之 — 10W条数据拷贝效率测试(接上篇 “Linq杂谈之 — Linq导入Excel”)

           上篇提要:

           接到一个需求,实现一个小功能—导入Excel,想想诸位活跃于.NET平台上的兄弟们,其中应该有相当一部分是从事如信息系统类开发的,所以小弟在这里姑且臭屁一下导入Excel的几种实现方法,如有错误之处,烦请大虾指正。

           1、 Excel导入 — 循环执行插入操作,批量导入数据

           2、 Excel导入 — 使用Linq提供的InsertAllOnSubmit方法,批量导入数据

           3、 Excel导入 — 使用SqlBulkCopy的WriteToServer方法,批量导入数据

          本篇重点: 

          在上一篇中谈到了.NET的三种数据拷贝方法,但是并没有做性能测试,今天闲来无事,索性做下性能测试,测试数据量10W条。

          机器配置及开发工具:CPU/P E5200 2.5GHZ

                        内存/2G

                        操作系统/Microsoft WINDOWS XP SP3

                        数据库/Microsoft SQL SERVER 2005

                        Framework/.Net Framework 3.5 SP1

                        开发工具/Microsoft  VS 2008 SP1

          原始数据表:IPInfo[IPid(Identity),IPFrom,IPTo,IPLocation,IPCity,IPToNumber,IPFromNumber]

          数据条数:345000条(这里用10W条来测试)

                 

          导入数据表:IPInfo1[IPid(Identity),IPFrom,IPTo,IPLocation,IPCity,IPToNumber,IPFromNumber]

          数据条数:0条,每次导入前,均清空IPInfo1表中数据

          首先是测试第一种方法,也就是直接用ADO.NET执行循环插入操作,批量导入数据,这里先贴上CODE:

    代码
    public static void InsertToIPInfo1_ADO(DataTable dt)
            {
                
    using (SqlConnection conn = new SqlConnection("Data Source=WSH-S0904003;Initial Catalog=GroupSell;User ID=sa;Password=123"))
                {
                    conn.Open();
                    
    string strSql = "Insert Into IPInfo1(IPFrom,IPTo,IPLocation,IPCity,IPToNumber,IPFromNumber) values (@IPFrom,@IPTo,@IPLocation,@IPCity,@IPToNumber,@IPFromNumber)";
                    
    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        SqlCommand Comm 
    = conn.CreateCommand();
                        Comm.CommandText 
    = strSql;
                        Comm.CommandType 
    = CommandType.Text;
                        Comm.Parameters.Add(
    "@IPFrom", SqlDbType.VarChar).Value = dt.Rows[i]["IPFrom"];
                        Comm.Parameters.Add(
    "@IPTo", SqlDbType.VarChar).Value = dt.Rows[i]["IPTo"];
                        Comm.Parameters.Add(
    "@IPLocation", SqlDbType.VarChar).Value = dt.Rows[i]["IPLocation"];
                        Comm.Parameters.Add(
    "@IPCity", SqlDbType.VarChar).Value = dt.Rows[i]["IPCity"];
                        Comm.Parameters.Add(
    "@IPToNumber", SqlDbType.VarChar).Value = dt.Rows[i]["IPToNumber"];
                        Comm.Parameters.Add(
    "@IPFromNumber", SqlDbType.VarChar).Value = dt.Rows[i]["IPFromNumber"];
                        Comm.ExecuteNonQuery();
                    }
                }
            }

             下面是调用方法:

    代码
    class Program
        {
            
    static void Main(string[] args)
            {
                
    //取10W数据
                DataTable dt = IpInfo_BLL.get10WData();
                
    //开始时间
                Console.WriteLine(DateTime.Now.ToString());
                DateTime db 
    = DateTime.Now;
                
                
    //Linq InsertAllOnSubmit()
                IpInfo_BLL.InsertToIPInfo1_Linq(dt);
                
                
    //ADO Insert
                
    //IpInfo_BLL.InsertToIPInfo1_ADO(dt);

                
    //SqlBulkCopy 
                
    //IpInfo_BLL.InsertToIPInfo1_SqlCopy(dt);

                
    //时间差值
                Console.WriteLine(DateTime.Now - db);
            }
            
        }

              下面是取DataTable数据的方法,索性也贴上来:

    代码
    public static DataTable get10WData() 
            {
                
    using (SqlConnection conn = new SqlConnection("Data Source=WSH-S0904003;Initial Catalog=GroupSell;User ID=sa;Password=123"))
                {
                    
    string strSql = "select top(100000) * from IPInfo";
                    DataSet ds 
    = new DataSet();
                    SqlDataAdapter adaper 
    = new SqlDataAdapter(strSql, conn);
                    adaper.Fill(ds);
                    
    return ds.Tables[0];
                }

            }

                  下面上结果:

               耗时2分34秒8281250(小数部分)

               下面我们测试第二种方法也就是使用Linq的InsertAllOnSubmit的方法实现数据拷贝:

    代码
    public static void InsertToIPInfo1_Linq(DataTable dt)
            {
                
    using (IPInfo1DataContext db = new IPInfo1DataContext()) 
                {
                    var query 
    = from q in dt.AsEnumerable()
                                select 
    new
                                {
                                    IPFrom 
    = q["IPFrom"].ToString().Trim(),
                                    IPTo 
    = q["IPTo"].ToString().Trim(),
                                    IPLocation 
    = q["IPLocation"].ToString().Trim(),
                                    IPCity 
    = q["IPCity"].ToString().Trim(),
                                    IPToNumber 
    = q["IPToNumber"].ToString().Trim(),
                                    IPFromNumber 
    = q["IPFromNumber"].ToString().Trim()
                                };
                    List
    <IPInfo1> list = new List<IPInfo1>();
                    
    foreach (var q in query)
                    {
                        IPInfo1 Entity 
    = new IPInfo1();
                        Entity.IPCity 
    = q.IPCity;
                        Entity.IPFrom 
    = q.IPFrom;
                        Entity.IPFromNumber 
    = q.IPFromNumber;
                        Entity.IPLocation 
    = q.IPLocation;
                        Entity.IPTo 
    = q.IPTo;
                        Entity.IPToNumber 
    = q.IPToNumber;
                        list.Add(Entity);
                    }
                    db.IPInfo1.InsertAllOnSubmit(list);
                    db.SubmitChanges();
                }
            }

                下面上结果:

              耗时1分50秒4843750(小数部分)

              下面我们来看第三种方法,使用SqlBulkCopy的WriteToServer方法,批量导入数据,大家要做好心理准备哦!

    代码
    public static void InsertToIPInfo1_SqlCopy(DataTable dt) 
            {
                
    using (SqlBulkCopy bulkCopy = new SqlBulkCopy("Data Source=WSH-S0904003;Initial Catalog=GroupSell;User ID=sa;Password=123"))
                {
                    bulkCopy.DestinationTableName 
    = "IPInfo1";
                    bulkCopy.WriteToServer(dt);
                }
            }

              下面上测试结果:

                耗时:0分5秒9532774(小数部分)

            测试总结:

            测试结果显示选择使用ADO.NET的基本方法来复制大批数据是错误的,也是耗时最长的,这里的测试是在本机进行的,如果数据库的Server跟网站的Server不在同一台服务器上,将会花费更多的时间。当然Linq的效率要比前者高些,略高2/5,但Linq操作起来便捷,对效率要求不是太苛刻的朋友,用Linq导入数据也是一种不错的选择,当然了,最棒的方法还是SqlBulkCopy,但是这种做法的缺点是要求EXCEL的格式必须与要导入的Table完全一致而且还要删除多余的Sheet。所以测试结果如上,朋友们可以视情况而定。

  • 相关阅读:
    Unity 游戏框架搭建 2019 (二十九) 方法所在类命名问题诞生的原因
    Unity 游戏框架搭建 2019 (二十七、二十八)弃用的代码警告解决&弃用的代码删除
    Unity 游戏框架搭建 2019 (二十六) 第一轮整理完结
    Unity 游戏框架搭建 2019 (二十五) 类的第一个作用 与 Obselete 属性
    排序算法之冒泡排序
    java中List Array相互转换
    java迭代器浅析
    谈谈java中遍历Map的几种方法
    浅谈java反射机制
    springMvc注解之@ResponseBody和@RequestBody
  • 原文地址:https://www.cnblogs.com/yangtongnet/p/1743713.html
Copyright © 2011-2022 走看看