• C# 海量数据瞬间插入到数据库的方法


    C# 海量数据瞬间插入到数据库的方法

    当我们在数据库中进行大量的数据追加时,是不是经常因为数据量过大而苦恼呢?
    而所谓的海量数据,一般也是上万级的数据,比如我们要添加一百万条数据,应该如何提高它的效率呢?

    Oracle数据库:

    普通肉垫式 

        什么叫批量插入呢,就是一次性插入一批数据,我们可以把这批数据理解为一个大的数组,而这些全部只通过一个SQL来实现,而在传统方式下,需要调用很多次的SQL才可以完成,这就是著名的“数组绑定”的功能。我们先来看一下传统方式下,插入多行记录的操作方式:

     1 //设置一个数据库的连接串,  
     2 string connectStr = "User Id=scott;Password=tiger;Data Source=";  
     3 OracleConnection conn = new OracleConnection(connectStr);  
     4 OracleCommand command = new OracleCommand();  
     5 command.Connection = conn;  
     6 conn.Open();  
     7 //通过循环写入大量的数据,这种方法显然是肉垫  
     8 for (int i = 0; i < recc; i++)  
     9 {  
    10     string sql = "insert into dept values(" + i.ToString() + "," + i.ToString() + "," + i.ToString() + ")";  
    11     command.CommandText = sql;  
    12     command.ExecuteNonQuery();  
    13 }   

    使用ODP特性

     1 //设置一个数据库的连接串  
     2 string connectStr = "User Id=scott;Password=tiger;Data Source=";  
     3 OracleConnection conn = new OracleConnection(connectStr);  
     4 OracleCommand command = new OracleCommand();  
     5 command.Connection = conn;  
     6 //到此为止,还都是我们熟悉的代码,下面就要开始喽  
     7 //这个参数需要指定每次批插入的记录数  
     8 command.ArrayBindCount = recc;  
     9 //在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候  
    10 //用到的是数组,而不是单个的值,这就是它独特的地方  
    11 command.CommandText = "insert into dept values(:deptno, :deptname, :loc)";  
    12 conn.Open();  
    13 //下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出  
    14 int[] deptNo = new int[recc];  
    15 string[] dname = new string[recc];  
    16 string[] loc = new string[recc];  
    17 // 为了传递参数,不可避免的要使用参数,下面会连续定义三个  
    18 // 从名称可以直接看出每个参数的含义,不在每个解释了  
    19 OracleParameter deptNoParam = new OracleParameter("deptno", OracleDbType.Int32);  
    20 deptNoParam.Direction = ParameterDirection.Input;  
    21 deptNoParam.Value = deptNo;  
    22 command.Parameters.Add(deptNoParam);  
    23 OracleParameter deptNameParam = new OracleParameter("deptname", OracleDbType.Varchar2);  
    24 deptNameParam.Direction = ParameterDirection.Input;  
    25 deptNameParam.Value = dname; command.Parameters.Add(deptNameParam);  
    26 OracleParameter deptLocParam = new OracleParameter("loc", OracleDbType.Varchar2);  
    27 deptLocParam.Direction = ParameterDirection.Input;  
    28 deptLocParam.Value = loc;  
    29 command.Parameters.Add(deptLocParam);  
    30 //在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL  
    31 for (int i = 0; i < recc; i++)  
    32 {  
    33     deptNo[i] = i;  
    34     dname[i] = i.ToString();  
    35     loc[i] = i.ToString();  
    36 }  
    37 //这个调用将把参数数组传进SQL,同时写入数据库  
    38 command.ExecuteNonQuery();  

    当数据量达到100万级别时,所用时间依然令人满意,最快一次达到890毫秒,一般为1秒左右。

    SqlServer数据库

    既然Oracle可以如此爽快,那么在SqlServer中是否也可以这样做呢?
    但是在SqlServer中却没有诸如ArrayBindCount 这样的操作属性。
    不过,我们却可以借助于BULK INSERT来进入海量数据的添加。
    代码:

     1 //设置一个数据库的连接串  
     2             string connectStr = "……";  
     3             SqlConnection conn = new SqlConnection(connectStr);  
     4             SqlCommand command = new SqlCommand();  
     5             command.CommandTimeout = 0;  
     6             command.Connection = conn;  
     7             /*说明: 
     8              * “c:\sql.txt”是一个预先生成的包含100条数据的文件 
     9              * 每一个字段的信息以“,”分割 
    10              * 每一条数据以“|”符号分隔 
    11              * 每10万条数据一个事务。 
    12              */  
    13             command.CommandText = "BULK INSERT TableB FROM 'c:\sql.txt' WITH (FIELDTERMINATOR = ',',ROWTERMINATOR ='|',BATCHSIZE = 100000)";  
    14             conn.Open();  
    15             //System.Data.SqlClient.SqlBulkCopy sqlBC  
    16             command.ExecuteNonQuery();  
    17   
    18             conn.Close();  

    虽然比不上Oracle那么变态,但是插入百万条数据也不过只用了几秒时间,比起我们平时的添加速度,无疑已经让人非常兴奋了吧,呵呵。

  • 相关阅读:
    Oracle 11g Release 1 (11.1) 单行函数——比较函数
    HTTP 协议演示——演示(55)
    Oracle 字符串分割函数 splitstr 和 splitstrbyseparators
    Bitmap 索引 vs. Btree 索引:如何选择以及何时使用?——15
    Oracle ——数据库 SQL 分页性能分析
    Oracle ——数据库 Hints
    Bitmap 索引 vs. Btree 索引:如何选择以及何时使用?——35
    Oracle 索引的数据结构
    Bitmap 索引 vs. Btree 索引:如何选择以及何时使用?——25
    回溯法>图的着色问题
  • 原文地址:https://www.cnblogs.com/miao-park/p/3860195.html
Copyright © 2020-2023  润新知