• c#ADO.NET / 用 SqlBulkCopy 类,海量批写入数据库


    SqlBulkCopy 类,使您可以用其他源的数据有效批量加载 SQL Server 表。

    Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表既可以在同一个服务器上,也可以在不同服务器上)。SqlBulkCopy 类允许编写提供类似功能的托管代码解决方案。还有其他将数据加载到 SQL Server 表的方法(例如 INSERT 语句),但相比之下 SqlBulkCopy 提供明显的性能优势。

    使用 SqlBulkCopy 类只能向 SQL Server 表写入数据。但是,数据源不限于 SQL Server;可以使用任何数据源,只要数据可加载到 DataTable instance 或可使用 DataReader 读取数据。

    ----------------------------------------------------------------

    示例一:
    同上方 msdn 连接的写法,不透过 DataTable 暂存所有要批写入的数据,而是直接用 
    DataReader + SqlBulkCopy 类,即时海量地批写入 :

    简易示例
    using(SqlConnection Conn = new SqlConnection(strConnString))
    {
    Conn.Open();
    SqlCommand Comm
    = new SqlCommand("SELECT EmployeeID, LastName, FirstName FROM Employees", Conn);

    SqlDataReader dr;

    dr
    = Comm.ExecuteReader();
    using (SqlConnection bcConn = new SqlConnection(strConnString))
    {
    bcConn.Open();
    using (SqlBulkCopy bc = new SqlBulkCopy(bcConn))
    {
    //要存入的数据库
    bc.DestinationTableName = "dbo.TestEmployees";

    //字段对应
    bc.ColumnMappings.Add("EmployeeID", "EmployeeID");
    bc.ColumnMappings.Add(
    "LastName", "LastName");
    bc.ColumnMappings.Add(
    "FirstName", "FirstName");
    try
    {
     
    for (int i = 0; i < 1000; i++)
      bc.WriteToServer(dr);
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    }
    if (dr != null)
    dr.Close();
    }
    }
    }

    在發現了 SqlBulkCopy 以後,發現它更是威力強大,現在就來介紹 SqlBulkCopy 的猛,如下例 :
    示例二 :
    (此例为先将要批写入的所有数据,暂存在一个 DataTable 里)

    进阶示例
    //一开始我们先产生一个 DataTable,用来装我们要写入的数据
    DataTable dt = new DataTable();
    dt.Columns.Add(
    "id", typeof(int));
    dt.Columns.Add(
    "name", typeof(string));

    //因为 SqlBulkCopy 的猛,就是海量地快速一次性写入能力,我们來跑 10 万条吧
    int i;
    for (i = 0; i < 100000; i++)
    {
    DataRow dr
    = dt.NewRow();
    dr[
    "name"] = i.ToString();
    dt.Rows.Add(dr);
    }

    //声明连接字符串
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ASPNETDBConnectionString1"].ConnectionString);

    conn.Open();

    //声明 SqlBulkCopy
    using (SqlBulkCopy sqlBC = new SqlBulkCopy(conn))
    {
    //設置一个批,写入多少条记录
    sqlBC.BatchSize = 1000;

    //設置逾時的秒数
    sqlBC.BulkCopyTimeout = 60;

    //設置 NotifyAfter 属性,以便在每拷贝 10000 条记录至数据表後,呼叫事件处理函数
    sqlBC.NotifyAfter = 10000;
    sqlBC.SqlRowsCopied
    += new SqlRowsCopiedEventHandler(OnSqlRowsCopied);

    //設置要写入的数据库
    sqlBC.DestinationTableName = "dbo.Table1";

    //对应数据行
    sqlBC.ColumnMappings.Add("id", "id");
    sqlBC.ColumnMappings.Add(
    "name", "name");

    //开始写入
    sqlBC.WriteToServer(dt);
    }

    conn.Dispose();

    void OnSqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
    {
    Response.Write(
    "---<br/>");
    }

    • 測試環境:SQL2005 Express
    • 測試資料量:10 万条
    • 測試次數:10 次
    • 平均秒數:2.3532 秒

    结论:太可怕啦,之前的写法,如果真的要写入 10 万条這种海量的数据,都需花费一分钟左右,但使用了 SqlBulkCopy 卻只要短短的兩秒钟。下表看的出來,如果记录条数很少,就沒必要使用 SqlBulkCopy 了。

    • 寫入十万条记录 10 次的平均秒數
      • 使用SqlBulkCopy:2.2051
      • 使用AddWithValue:63.418
    • 寫入一万条记录 10 次的平均秒數
      • 使用SqlBulkCopy:0.2188
      • 使用AddWithValue:6.3856
    • 寫入一千条记录 10 次的平均秒數
      • 使用SqlBulkCopy:0.0187
      • 使用AddWithValue:0.5805
    • 寫入一百条记录 10 次的平均秒數
      • 使用SqlBulkCopy:0.0062
      • 使用AddWithValue:0.0353
    • 寫入十条记录 10 次的平均秒數
      • 使用SqlBulkCopy:0.004
      • 使用AddWithValue:0.004
  • 相关阅读:
    python 数据结构与算法 day04 冒泡排序
    阿里代码扫描插件安装 (IDEA)
    Kafka
    女生赛训练 2
    2019 DISCS PrO High School Division
    计算机安全之密码安全 从 Hash 到 MD5
    CodeForces Round #559 Div.2
    CodeForces Round #558 Div.2
    CodeForces Round #560 Div.3
    NCD 2019 (AK)
  • 原文地址:https://www.cnblogs.com/andy_tigger/p/2393262.html
Copyright © 2020-2023  润新知