본문 바로가기

IT/Winform & Devexpress

C# MS SQL Bulk insert - 속도비교, 방법, Bulk insert into MS SQL




대용량 Datatable(즉 Rows가 많은) 을 SQL Server에 Insert할 때 속도에 유의할 필요가 있습니다.



1. 우선 제가 기존에 쓰던방식 - 하나씩 insert하기

const string sql = "INSERT INTO [Test] ([Value]) Values (@Value)";

    for (var i = 0; i < count; i++)

    {

        connection.Execute(sql, new { Value = Guid.NewGuid().ToString()});

    }


저의 환경에서 10,000 rows insert할 때 54,533ms의 시간이 걸렸습니다. 1초당 약 183 레코드를 저장한다고 생각하시면 됩니다.


2. 한번에 1000개씩 insert

foreach (var batch in Enumerable.Range(0, count).Chunk(1000))

    {

        if (batch.Length == 0) continue;

        var sql = "INSERT INTO [Test] ([Value]) VALUES \r\n" + string.Join(",\r\n", batch.Select(x => $"('{Guid.NewGuid().ToString()}')"));

        connection.Execute(sql);

    }

SQL Server는 여러 레코드를 단일 sql문으로 insert할 수 있도록 지원합니다. 그러니까 1000개를 한번에 insert하는 것이죠.

제 환경에서 100만개의 레코드를 insert하니 22,256ms의 시간이 결렸습니다. 초당 44,931개 수준


3. 더빠른 Bulk Copy

var table = new DataTable();

    table.Columns.Add("Value", typeof(string));


    for (var i = 0; i < count; i++)

    {

        table.Rows.Add(Guid.NewGuid().ToString());

    }


    using (var bulk = new SqlBulkCopy(this.connection))

    {

        bulk.DestinationTableName = "test";

        bulk.WriteToServer(table);

SQL Server 는 bulk insert를 지원하죠 c#에서는 더 쉽게 접근 할 수 있어요.

제 환경에서 100만개의 레코드를 9,315ms에 끝내버립니다. 초당 107,353개 수준인거에요


4. C# Datatable MS SQL로 insert(Bulk copy)

var table = new DataTable();


    // read the table structure from the database

    using (var adapter = new SqlDataAdapter($"SELECT TOP 0 * FROM test", this.connection))

    {

        adapter.Fill(table);

    };


    for (var i = 0; i < count; i++)

    {

        var row = table.NewRow();

        row["Value"] = Guid.NewGuid().ToString(); 

        table.Rows.Add(row);

    }


    using (var bulk = new SqlBulkCopy(this.connection))

    {

        bulk.DestinationTableName = "test";

        bulk.WriteToServer(table);

    }

C#에서 우선 DataTable을 만들고 dst table을 지정합니다. 그러고나서 값을 때려박으면 되요 참 쉽죠?


대충 100~1000row는 그냥 insert해도 될 것 같은데 그 이상이면 한번쯤 고려해보세요

반응형