2011-03-30 5 views
4

이 코드는 정수 배열을 직렬화 한 다음 SQL 테이블에 삽입합니다. 내가 원하는만큼 빠르지는 않습니다. 좀 더 효율적으로 할 수 있을까요?어떻게이 C# 함수/SQL 삽입 속도를 높일 수 있습니까?

감사합니다. 내가이이 기능을 분할하는 조언을

var array = new int[BitConverter.GetBytes(0).Length * items.Length]; 
using (MemoryStream stream = new MemoryStream(array)) 
{ 
    // ... rest is almost the same 
} 
+0

BitStream을 사용하는 대신 MemoryStream 주위에 BinaryWriter를 래핑 해 보았습니까? 또한 결국 배열로 변환하기 때문에 왜 배열이 아닌 스트림을 사용합니까? 당신은 이미 크기를 알고있다. (items.Count * 4) –

+0

sqlConnection은 private 변수인가? – rsbarro

+0

예, sqlConnection은 prvate 변수입니다. – user404068

답변

10

: 나는 시도 할 것이다

public void SetItem(long Id, int[] items) 
    { 
     using (MemoryStream stream = new MemoryStream()) 
     { 
      foreach (int d in items) 
      { 
       var bin = BitConverter.GetBytes(d); //Serialize 
       stream.Write(bin, 0, bin.Length); 
      } 
      var array = stream.ToArray(); 

      using (SqlCommand cmd = new SqlCommand("INSERT INTO Items(Id, Item, DateCreated) VALUES (@Id, @binaryValue, @dateCreated)", sqlConnection)) 
      { 
       cmd.Parameters.Add("@binaryValue", SqlDbType.VarBinary, array.Length).Value = array; 
       cmd.Parameters.Add("@Id", SqlDbType.BigInt).Value = Id; 
       cmd.Parameters.Add("@dateCreated", SqlDbType.DateTime2).Value = DateTime.Now; 
       cmd.ExecuteNonQuery(); 
      } 
     } 
    } 
1

우선은 메모리 스트림에 대한 byte[]의 사전 할당입니다. 하나는 바이트 배열에 관한 것이고 다른 하나는 DB에 삽입하기위한 것입니다.

그런 다음 프로파일 링을 실행하고 바이트 배열 코드가 느리거나 db 문제인지 확인하십시오.

아마 당신은 당신이 명령을 삽입하여 :)

1

당신은, 프로 시저를 만들 수 있습니다 저하되지 않는 무언가를 가속화하기 위해 노력하고 있습니다. 절차가 이미 SQL에 대한이 같은

뭔가 컴파일되어 있기 때문에 빠른 :

SqlConnection conn = new SqlConnection(actual_string); 
conn.Open(); 

// Create the command string 
SqlCommand cmd = new SqlCommand("EXEC insert_test @var1, @var2, @var3, @str1, @str2", conn); 

// Iterate through all of the objects 
try { 
    for (int i = 0; i < 10000; i++) { 
     cmd.Parameters.Clear(); 
     cmd.Parameters.Add(new SqlParameter("@var1", var1)); 
     cmd.Parameters.Add(new SqlParameter("@var2", var2)); 
     cmd.Parameters.Add(new SqlParameter("@var3", var3)); 
     cmd.Parameters.Add(new SqlParameter("@str1", str1)); 
     cmd.Parameters.Add(new SqlParameter("@str2", str2)); 

     // Read in all the data 
     cmd.ExecuteNonQuery(); 
    } 
} finally { 
    conn.Close(); 
} 

을하지만 내 취향은 절차에 XML을 보낼 수 있습니다.

당신이 행을 많이 삽입하는 경우 당신이 good article

6

에서 자세한 내용을 볼 수는 SqlBulkCopy 클래스는 insert 시간을 많이 호출하는 것보다 훨씬 빠릅니다. 이 내용은 blog post for an example을 참조하십시오. 나의 첫번째 성향이 미리 할당 배열하는 것

+0

나는 또한이 접근법을 좋아한다. –

+0

uhm ... 그는 단 하나의 삽입물을 수행합니다. – BlackTigerX

1

MemoryStream에서 사용 한 다음에 쓰기 BinaryWriter를 사용한다 :

var OutputArray = new byte[items.Length * 4]; 
using (var ms = new MemoryStream(OutputArray)) 
{ 
    using (var writer = new BinaryWriter(ms)) 
    { 
     foreach (var i in items) 
     { 
      writer.Write(i); 
     } 
    } 
} 
// You can now send the OutputArray to SQL server 

BinaryWriter

내부적 BitConverter.GetBytes를 사용하지 않습니다. 오히려 int에서 한 번에 하나씩 바이트를 추출하여 버퍼에 저장합니다. 그런 다음 버퍼가 스트림에 기록됩니다. 반면에 BitConverter은 호출 할 때마다 새로운 4 바이트 버퍼를 할당합니다.

+0

조금 빠릅니다. 감사합니다. – user404068

관련 문제