C#에서 Bulk Insert(대량 삽입) 최적화하기 – SQL Server & Oracle 완벽 가이드
데이터베이스에서 대량 데이터를 삽입할 때, 개별 INSERT 문을 반복 실행하는 방식은 성능이 매우 떨어지고, 네트워크 및 데이터베이스 리소스를 비효율적으로 사용할 수 있습니다.
Bulk Insert(대량 삽입) 기술을 활용하면 대량 데이터를 더 빠르게 처리할 수 있으며, 데이터베이스 성능을 크게 향상시킬 수 있습니다. 이번 글에서는 C#에서 SQL Server 및 Oracle을 대상으로 효율적인 Bulk Insert 방법을 설명하고, 최적의 성능을 내기 위한 팁을 공유하겠습니다.
1. C#에서 Bulk Insert를 수행하는 다양한 방법
C#에서 Bulk Insert를 수행하는 대표적인 방법은 다음과 같습니다.
✅ SQL Server
- SqlBulkCopy 활용 (가장 빠름)
- Table-Valued Parameter (TVP) + Stored Procedure 활용
- Dapper의 Execute를 이용한 다중 삽입
- Entity Framework의 AddRange와 SaveChangesAsync 사용
✅ Oracle
- OracleBulkCopy 활용 (가장 빠름)
- PL/SQL의 FORALL 문을 활용한 대량 삽입
- Stored Procedure + TABLE 타입을 이용한 대량 삽입
각 방법의 특징과 코드 예제를 살펴보겠습니다.
2. SQL Server에서 Bulk Insert 수행 방법
SQL Server는 대량 삽입을 최적화하기 위해 다양한 기능을 제공합니다.
2-1. SqlBulkCopy를 활용한 대량 삽입 (SQL Server 전용)
SqlBulkCopy는 .NET에서 SQL Server로 데이터를 한 번에 전송할 수 있는 가장 빠른 방법입니다.
🔹 특징
- SQL Server에서 가장 빠른 대량 삽입 방법
- 네트워크 오버헤드를 줄이고 직접 데이터베이스로 스트리밍
- 트랜잭션을 사용하여 안정적인 데이터 삽입 가능
🔹 C# 코드 예제
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
class Program
{
static void Main()
{
string connectionString = "Server=your_server;Database=your_db;User Id=your_user;Password=your_password;";
List<Person> people = new List<Person>
{
new Person { FirstName = "John", LastName = "Doe", Age = 30 },
new Person { FirstName = "Jane", LastName = "Smith", Age = 25 },
};
BulkInsert(people, connectionString);
Console.WriteLine("SQL Server Bulk Insert 완료!");
}
static void BulkInsert(List<Person> people, string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = "Persons";
DataTable table = new DataTable();
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Age", typeof(int));
foreach (var person in people)
{
table.Rows.Add(person.FirstName, person.LastName, person.Age);
}
bulkCopy.WriteToServer(table);
}
}
}
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
✅ 장점
- SQL Server에서 가장 빠름
- 최소한의 네트워크 오버헤드로 최적화됨
⚠️ 단점
- SQL Server에서만 사용 가능
- 테이블 매핑을 직접 관리해야 함
2-2. Table-Valued Parameter (TVP) + Stored Procedure 활용
SQL Server에서 **Table-Valued Parameter(TVP)**를 활용하면 다중 행을 한 번에 삽입할 수 있어 성능이 더욱 향상됩니다.
🔹 SQL Server에서 Table Type 생성
CREATE TYPE PersonTableType AS TABLE
(
FirstName NVARCHAR(50),
LastName NVARCHAR(50),
Age INT
);
🔹 저장 프로시저 생성
CREATE PROCEDURE BulkInsertPersons
@Persons PersonTableType READONLY
AS
BEGIN
INSERT INTO Persons (FirstName, LastName, Age)
SELECT FirstName, LastName, Age FROM @Persons;
END
🔹 C# 코드에서 실행
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = "Server=your_server;Database=your_db;User Id=your_user;Password=your_password;";
List<Person> people = new List<Person>
{
new Person { FirstName = "Alice", LastName = "Johnson", Age = 28 },
new Person { FirstName = "Bob", LastName = "Lee", Age = 35 },
};
BulkInsertWithTVP(people, connectionString);
Console.WriteLine("TVP를 이용한 Bulk Insert 완료!");
}
static void BulkInsertWithTVP(List<Person> people, string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand("BulkInsertPersons", connection))
{
cmd.CommandType = CommandType.StoredProcedure;
DataTable table = new DataTable();
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Age", typeof(int));
foreach (var person in people)
{
table.Rows.Add(person.FirstName, person.LastName, person.Age);
}
SqlParameter param = cmd.Parameters.AddWithValue("@Persons", table);
param.SqlDbType = SqlDbType.Structured;
cmd.ExecuteNonQuery();
}
}
}
}
✅ 장점
- SqlBulkCopy보다 유연함
- TVP를 사용하여 네트워크 오버헤드를 줄일 수 있음
⚠️ 단점
- SQL Server에서만 사용 가능
3. Oracle에서 Bulk Insert 수행 방법
Oracle에서는 대량 삽입을 최적화하기 위해 OracleBulkCopy, PL/SQL FORALL, 그리고 Stored Procedure를 활용할 수 있습니다.
3-1. OracleBulkCopy를 활용한 대량 삽입
OracleBulkCopy는 Oracle에서 SQL Server의 SqlBulkCopy와 유사한 방식으로 작동합니다.
🔹 C# 코드 예제
using System;
using System.Data;
using Oracle.ManagedDataAccess.Client;
using System.Collections.Generic;
class Program
{
static void Main()
{
string connectionString = "User Id=your_user;Password=your_password;Data Source=your_oracle_db";
List<Person> people = new List<Person>
{
new Person { FirstName = "John", LastName = "Doe", Age = 30 },
new Person { FirstName = "Jane", LastName = "Smith", Age = 25 },
};
BulkInsertOracle(people, connectionString);
Console.WriteLine("Oracle Bulk Insert 완료!");
}
static void BulkInsertOracle(List<Person> people, string connectionString)
{
using (OracleConnection connection = new OracleConnection(connectionString))
{
connection.Open();
using (OracleBulkCopy bulkCopy = new OracleBulkCopy(connection))
{
bulkCopy.DestinationTableName = "Persons";
DataTable table = new DataTable();
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Age", typeof(int));
foreach (var person in people)
{
table.Rows.Add(person.FirstName, person.LastName, person.Age);
}
bulkCopy.WriteToServer(table);
}
}
}
}
✅ 장점
- Oracle에서 가장 빠른 대량 삽입 방법
⚠️ 단점
- ODP.NET 설치 필요
결론
SQL Server와 Oracle에서 최적의 Bulk Insert 방법을 선택하세요! 🚀
.png)
댓글
댓글 쓰기