2014-03-07 1 views
1

.dat 파일에는 파일 크기가 245kb 인 바이너리 데이터가 들어 있습니다. 따라서 총 2 진수는 2 백만입니다.더 빠른 방법은 비트 배열을 foreach하고 비트 숫자를 데이터베이스에 삽입합니다.

이진수로 읽고 데이터베이스에 이진수를 저장해야합니다. 여기 내가 한 것 :

byte[] data = File.ReadAllBytes(dat_file); 

    BitArray bits = new BitArray(data);      

    int id_card = 1; 

    for (int i = 0; i < bits.Length; i++) 
    { 
     if (stop) 
     { 
     break; 
     } 
     //Insert to database 
     save_to_database(Convert.ToInt16(bits[i]),id_card); 

     id_card++; 

     double perc = (double)i/ (double)bits.Length;    

     this.btnSubmit.Invoke(new MethodInvoker(delegate { btnSubmit.Text = perc.ToString("P"); }));    


    } 

그러나 문제는 비트 배열을 foreach하여 데이터베이스에 저장할 때 매우 오랜 시간이 걸립니다. 착각하지 않으면 600k에 도달하는 데 약 1 시간이 걸렸습니다.

어떤 아이디어로 문제를 해결할 수 있습니까? 나는 5 개 이상의 파일을 바이너리로 읽고 데이터베이스에 저장해야한다.

+0

매 반복마다 버튼 텍스트를 정말로 업데이트해야합니까? 아니면 디버깅 목적으로 그렇게 했습니까? –

+0

@JimMischel, 디버깅 목적으로 만 사용 – Chuki2

+0

왜이 데이터를 저장 비트로 분할하려고합니까? –

답변

1

데이터베이스에 어떻게 쓰나요? 데이터베이스 엔진이란 무엇입니까?

제게 저속의 로우 엔드 PC에서 SQL Server의 localdb 인스턴스에 절대적으로 같은 양의 비트를 생성하고 쓰려면 약 20 초가 걸립니다. 파일 시스템에서 파일을 읽어 들이고 비트를 빠른 서버에 기록하는 것보다 분명히 느립니다.

단위 테스트 :

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System; 
using System.Data; 
using System.Data.SqlClient; 

namespace BitsTest 
{ 
    [TestClass] 
    public class BitsTester 
    { 
     [TestMethod] 
     public void BitsTest() 
     { 
      // random seed for emulating bit-array file 
      Random rand = new Random(); 

      DataTable table = new DataTable(); 
      table.Columns.Add("bit",typeof(bool)); 

      string cs = @"Data Source=(localdb)\v11.0;Initial Catalog=bittest;Integrated Security=True"; 

      // 2007040 records = 245kb of bits 
      for (int i = 0; i < 2007040; i++) 
       table.Rows.Add(rand.Next() % 2 == 0); 

      using (SqlBulkCopy bulk = new SqlBulkCopy(cs)) 
      { 
       bulk.DestinationTableName = "bits"; 
       bulk.WriteToServer(table); 
      } 
     } 
    } 
} 

겠어요 - 표시 한 코드에 문제가 없습니다. 실제 병목 현상을 찾기 위해 코드를 프로파일 링하십시오.

+0

좋은 방법, SqlBulkCopy가 기존 값을 확인할 수 있습니까? 그렇다면 true이면 건너 뛰고 다른 레코드를 계속 사용합니까? – Chuki2

+0

이 코드는 정확히 내 답변에서 의미하는 것입니다. 값 비싼 처리를 먼저 수행 한 다음 IO를 수행하십시오. –

+0

@ Chuki2, 아니요. 간단한 SQL과 마찬가지로 동일합니다. 이렇게하려면 먼저 임시 테이블에 값을 쓰고 두 번째 단계로 기존 테이블과 "where"필터를 결합하여 업데이트해야합니다. 이 작업을 수행하는 비싸지 않은 방법은 없습니다. – rufanov

3

모든 반복 작업에서 데이터베이스 삽입 작업을 수행하고 있습니다.

삽입 작업을 루프 외부에두고 결과를 목록에 저장 한 다음 데이터베이스에 대량 삽입을 수행합니다.

+0

제안 해 주셔서 감사합니다. – Chuki2

0

또 다른 방법은 데이터베이스에서 BLOB 필드를 사용하는 것입니다. http://support.microsoft.com/kb/317016을보고 데이터베이스에서 이진 데이터를 읽거나 쓰는 방법을 알아보십시오.

관련 문제