DataTable을 사용하는 것보다 SqlBulkCopy를 사용하는 더 빠른 방법이 있습니까?

c# sqlbulkcopy sql-server

문제

내 응용 프로그램에 많은 양의 레코드를로드하고 (1 백만 +) 처리량을 처리합니다. 처리는 모두 메모리에 있어야합니다.

이후에, (지금 수정 된) 모든 레코드를 빈 테이블에 덤프하려고합니다.

레코드를로드하는 데는 몇 초 밖에 걸리지 않으며 많은 양의 MyRecord 항목으로 끝납니다.

SqlBulkCopy 사용하여 절약하는 데는 몇 초 밖에 걸리지 않습니다.

그러나 SqlBulkCopy (내가 믿는)가 필요 DataTable 과에 내 기록을로드 - DataTable 사용 분에 약 7500 기록 - 느린을

dataTable.Rows.Add(myRecord.Name, myRecord.Age, ....)

이 중간 단계를 수행하는 더 빠른 방법이 있습니까?

수락 된 답변

지연은 서버에 보내기 전에 모든 것을 DataTable로 버퍼링해야하기 때문에 발생합니다. 더 나은 성능을 얻으려면 레코드를 SqlBulkCopy immediatelly로 보내야하며 클래스가 자체 버퍼링 및 일괄 처리를 사용하도록해야합니다.

SqlBulkCopy는 IDataReader와 함께 작동 할 수 있습니다. 모든 ADO.NET 데이터 판독기는이 인터페이스를 구현하므로 모든 데이터 판독기에서 읽은 데이터를 SqlBulkCopy로 푸시 할 수 있습니다.

다른 경우에는 개체의 IEnumerable이 있다고 가정하면 FastMember 패키지의 Marc Gravel의 ObjectReader를 사용하여 IEnumerable 위에 IDataReader를 만들 수 있습니다. 이 데이터 판독기는 한 번에 모든 것을로드하지 않으므로 SqlBulkCopy가 데이터를 요청할 때까지 캐시 된 데이터가 없습니다.

Marc Gravel의 예제 복사 :

IEnumerable<SomeType> data = ... 

using(var bcp = new SqlBulkCopy(connection)) 
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) 
{ 
  bcp.DestinationTableName = "SomeTable"; 
  bcp.WriteToServer(reader); 
}

인기 답변

나는 그 문제가 뭔지 모른다. 아래의 프로그램은 1 초 이내에 실행됩니다. 나는 느린 속도가 데이터를 읽고 DataTable에 쓰지 않기 때문이라고 생각한다.

       static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Col A", typeof(int));
            dt.Columns.Add("Col B", typeof(string));
            dt.Columns.Add("Col C", typeof(int));
            dt.Columns.Add("Col D", typeof(string));
            dt.Columns.Add("Col E", typeof(int));
            dt.Columns.Add("Col F", typeof(string));
            dt.Columns.Add("Col G", typeof(int));
            dt.Columns.Add("Col H", typeof(string));
            dt.Columns.Add("Col I", typeof(int));
            dt.Columns.Add("Col J", typeof(string));

            DateTime begin = DateTime.Now;

            for (int i = 0; i < 7500; i++)
            {
                dt.Rows.Add(new object[] {
                    i + 10000, "b", i + 20000, "d", i + 30000, "f", i + 40000, "h", i + 50000, "i"
                });
            }

            DateTime end = DateTime.Now;

            Console.WriteLine((end - begin).ToString());

            Console.ReadLine();
        }


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow