대용량 데이터 삽입 및 업데이트의 경우 ADO.NET은 실제로 JDBC만큼 좋지 않습니다. JDBC는 일괄 작업을 위한 통합 모델을 사용하기가 매우 편리합니다.
ReadyStatement ps = conn.prepareStatement("arg1,args2.... 삽입 또는 업데이트");
그럼 넌 할 수 있어
for(int i=0;i<1000000000000000;i++){
ps.setXXX(realArg);
.....
ps.addBatch();
if(i%500==0){ //한 번에 500개의 항목이 제출되었다고 가정합니다.
ps.executeBatch();
//매개변수 배치 지우기
}
}
ps.executeBatch();
이러한 작업은 매우 높은 성능을 제공할 뿐만 아니라 매우 편리합니다. 일반적으로 ADO.NET에서는 이러한 기능을 구현하려면 Command 인터페이스나 DataAdapter 인터페이스에서 직접 Addbat 및 CommitBat API를 제공해야 하지만 ADO는 이러한 작업을 수행합니다. NET의 하지만 그렇게 간단하게 구현되지는 않으며 개발자가 복잡한 해결 방법을 거쳐야 합니다.
삽입 작업 수가 많은 경우 빈 DataTable을 사용하여 삽입할 행을 추가한 다음 특정 횟수만큼 제출한 후 테이블을 지울 수 있습니다.
구현하기가 너무 복잡하지 않습니다.
DateTime 시작 = DateTime.Now;
문자열 연결문자열 = ...;
using(SqlConnection conn = new SqlConnection(connectionString))...{
conn.Open();
SqlDataAdapter sd = 새로운 SqlDataAdapter();
sd.SelectCommand = new SqlCommand("CurrentTest에서 devid,data_time,data_value 선택", conn);
sd.InsertCommand = new SqlCommand("CurrentTest에 삽입(devid,data_time,data_value) "
+ "값 (@devid,@data_time,@data_value);", conn);
sd.InsertCommand.Parameters.Add("@devid", SqlDbType.Char, 18, "devid");
sd.InsertCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
sd.InsertCommand.Parameters.Add("@data_value", SqlDbType.Int, 8, "data_value");
sd.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = 0;
DataSet 데이터세트 = new DataSet();
sd.Fill(데이터세트);
랜덤 r = new Random(1000);
for (int i = 0; i < 100000; i++) ...{
object[] 행 = ...{"DEVID"+i,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),r.Next(1,1000) };
데이터세트.테이블[0].Rows.Add(행);
if (i % 300 == 0) ...{
sd.Update(dataset.Tables[0]);
데이터세트.테이블[0].Clear();
}
}
sd.Update(dataset.Tables[0]);
데이터세트.테이블[0].Clear();
sd.Dispose();
데이터세트.Dispose();
conn.Close();
}
TimeSpan ts = DateTime.Now - 시작;
MessageBox.Show("ts = " + ts.TotalMilliseconds);
이 테스트에서는 100,000개의 데이터를 삽입하는 데 28초가 걸렸습니다. 그러나 일괄 업데이트 및 전 세계 검색의 경우 레코드가 DataSet에 채워지고 행이 추출됩니다.
업데이트하려면 적은 양의 데이터를 사용한 테스트의 경우 100,000개의 데이터를 DataSet에 채우는 것이 더 이상 작동하지 않습니다. 수백만 개이면 먼저 레코드를 가져와야 합니까? 즉, 이러한 레코드를 쿼리하려면 업데이트하려는 레코드를 선택해야 합니까?
따라서 업데이트할 레코드를 추가하기 위해 여전히 빈 DataTable을 사용합니다.
sd.SelectCommand = new SqlCommand("1=0인 CurrentTest에서 devid,data_time,data_value 선택", conn);
//1=0 조건은 빈 테이블을 보장합니다.
sd.UpdateCommand = new SqlCommand("update CurrentTest set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = 0;
for(int i=0;i<300;i++){
......................
데이터세트.테이블[0].Rows.Add(행);
}
sd.Update(dataset.Tables[0]);
먼저 300개의 레코드를 업데이트해 보십시오. 성공하면 루프의 모든 레코드가 업데이트되지만 삽입 작업에는 빈 테이블이므로 InsertCommand가 필요하다는 메시지가 표시되고 이때 RowState가 추가됩니다.
이때 업데이트가 데이터베이스로 전송되면 삽입 작업이 수행되며 업데이트할 수 없습니다.
for(int i=0;i<300;i++){
......................
row = {초기화 값 채우기};
데이터세트.테이블[0].Rows.Add(행);
}
데이터세트.AcceptChanges();
for(int i=0;i<300;i++){
......................
데이터 세트.테이블[0].Rows[i][x] = "xxxxxxx";
......................
}
sd.Update(dataset.Tables[0]);
먼저 DataTable에 데이터를 삽입한 다음 AcceptChanges()를 사용하여 RowState를 UnChanged로 수정한 다음 테이블의 데이터를 수정하여 UnChanged 상태를 변경합니다.
DataTable을 현재 상태에서 원본으로 변경한 다음 DataTable의 행을 업데이트합니다.
업데이트는 성공했는데 정말 불편하네요.
아이디어를 조정하고 먼저 데이터베이스에서 200개의 항목(일괄 업데이트 크기)을 가져와 원본 DataTable을 직접 가져옵니다.
sd.SelectCommand = new SqlCommand("CurrentTest에서 상위 200개 devid,data_time,data_value 선택", conn);
DataSet 데이터세트 = new DataSet();
sd.Fill(데이터세트);
이 200개의 공간을 사용하여 업데이트할 다른 데이터를 입력하고 다음을 확인하세요.
for (int i = 0; i < 100; i++)
{
데이터 세트.Tables[0].Rows[i].BeginEdit();
Dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
Dataset.Tables[0].Rows[i]["data_value"] = 100;
Dataset.Tables[0].Rows[i]["devid"] = "DEVID"+(i+10000);//DEVID10000에서 DEVID10200으로 레코드 업데이트
데이터 세트.Tables[0].Rows[i].EndEdit();
}
sd.Update(dataset.Tables[0]);
좋아요, 성공입니다. ㅎㅎ 이 공간에 업데이트할 데이터를 계속 채워넣고, 가득 차면 제출하세요. 이렇게 하면 100,000개의 데이터를 업데이트하는 데 몇 사이클밖에 걸리지 않습니다.
DateTime 시작 = DateTime.Now;
문자열 연결문자열 = "";
using(SqlConnection conn = new SqlConnection(connectionString))...{
conn.Open();
SqlDataAdapter sd = 새로운 SqlDataAdapter();
sd.SelectCommand = new SqlCommand("CurrentTest에서 상위 200개 devid,data_time,data_value 선택", conn);
DataSet 데이터세트 = new DataSet();
sd.Fill(데이터세트);
랜덤 r = new Random(1000);
sd.UpdateCommand = new SqlCommand("현재 테스트 업데이트 "
+ " set data_time = @data_time,data_value = @data_value 여기서 devid = @devid", conn);
sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = 0;
for (int 개수 = 0; 개수 < 100000;)
...{
for (int i = 0; i < 200; i++,count++)
...{
데이터 세트.Tables[0].Rows[i].BeginEdit();
Dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
Dataset.Tables[0].Rows[i]["data_value"] = 100;
Dataset.Tables[0].Rows[i]["devid"] = "DEVID"+count;
데이터 세트.Tables[0].Rows[i].EndEdit();
}
sd.Update(dataset.Tables[0]);
}
데이터세트.테이블[0].Clear();
sd.Dispose();
데이터세트.Dispose
http://www.cnblogs.com/Seabiscuit/archive/2010/05/25/1743341.html