C# Microsoft Sql Server 資料庫批次(大量)寫入示範

在上一篇 C# Microsoft Sql Server 資料庫使用完整 CRUD 示範 (Microsoft.Data.SqlClient)寫完基礎後,那大量新增呢?

測試資料表:
    
create table users
(
    id   INT PRIMARY KEY IDENTITY (1,1),
    name VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE
)
    

連接字串:
    
    private const string ConnectionString =
        "Server=localhost;Database=mydb;User=ruyut;Password=ruyut;TrustServerCertificate=true";
    

首先使用最慢的方式:
    
using var connection = new SqlConnection(ConnectionString);
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = "INSERT INTO users (name, email) VALUES (@name, @email)";
command.Parameters.Add("@name", SqlDbType.NVarChar);
command.Parameters.Add("@email", SqlDbType.NVarChar);
for (int i = 0; i < 1000000; i++)
{
    command.Parameters["@name"].Value = "Ruyut" + i;
    command.Parameters["@email"].Value = "ruyut" + i + "@ruyut.com";
    command.ExecuteNonQuery();
}

command.Dispose();
connection.Dispose();
    

嗯 100 萬筆跑了 930,965 毫秒,約等於 15.5 分鐘,真的是有夠慢,那有沒有更快的方式呢?

SqlBulkCopy

    
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("name", typeof(string)));
dataTable.Columns.Add(new DataColumn("email", typeof(string)));

for (int i = 0; i < 1000000; i++)
{
    DataRow row = dataTable.NewRow();
    row["name"] = $"Ruyut{i}";
    row["email"] = $"ruyut{i}@ruyut.com";
    dataTable.Rows.Add(row);
}

// 上面塞入 DataTable 花了 1,304 毫秒


using var connection = new SqlConnection(ConnectionString);
connection.Open();
using var sqlBulkCopy = new SqlBulkCopy(connection);
sqlBulkCopy.DestinationTableName = "users";
sqlBulkCopy.ColumnMappings.Add("name", "name");
sqlBulkCopy.ColumnMappings.Add("email", "email");
sqlBulkCopy.WriteToServer(dataTable);

// 將 DataTable 塞入資料庫花了 6,493 毫秒
    

總共才花了 7,797 毫秒,10 秒都不到...那之前的是真的慢...

參考資料:
Microsoft.Learn - SqlBulkCopy Class

留言