สำหรับการแทรกและอัปเดตข้อมูลจำนวนมาก ADO.NET นั้นไม่ดีเท่ากับ JDBC มีโมเดลแบบครบวงจรสำหรับการดำเนินการแบบแบตช์ ซึ่งสะดวกมากในการใช้งาน:
PreparationStatement ps = conn.prepareStatement("แทรกหรืออัปเดต arg1,args2....");
ถ้าอย่างนั้นคุณก็ทำได้
สำหรับ(int i=0;i<1000000000000000;i++){
ps.setXXX(realArg);
-
ปล.addBatch();
if(i%500==0){/ //สมมติว่ามีการส่งรายการห้าร้อยรายการครั้งเดียว
PS.executeBatch();
//ล้าง Parame Batch
-
-
PS.executeBatch();
การดำเนินการดังกล่าวไม่เพียงแต่ให้ประสิทธิภาพสูงมากเท่านั้น แต่ยังสะดวกมากอีกด้วย โดยปกติแล้ว ใน ADO.NET ในการใช้ฟังก์ชันดังกล่าว ควรจัดเตรียม Addbat และ CommitBat API โดยตรงในอินเทอร์เฟซ Command หรืออินเทอร์เฟซ DataAdapter แต่ ADO NET แต่มันไม่ได้ถูกนำมาใช้อย่างง่าย ๆ แต่ต้องการให้นักพัฒนาใช้วิธีการแก้ไขปัญหาที่ซับซ้อน
สำหรับการดำเนินการแทรกจำนวนมาก คุณสามารถใช้ DataTable ว่างเพื่อเพิ่มแถวที่จะแทรก จากนั้นล้างตารางหลังจากส่งตามจำนวนที่กำหนด
การดำเนินการไม่ซับซ้อนเกินไป:
DateTime start = DateTime.Now;
การเชื่อมต่อสตริงString = ...;
ใช้(SqlConnection conn = new SqlConnection(connectionString))...{
conn.เปิด();
SqlDataAdapter sd = SqlDataAdapter ใหม่();
sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest", conn);
sd.InsertCommand = new SqlCommand("insert into 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;
ชุดข้อมูล ชุดข้อมูล = ชุดข้อมูลใหม่ ();
sd.Fill(ชุดข้อมูล);
สุ่ม r = สุ่มใหม่ (1,000);
สำหรับ (int i = 0; i < 100,000; i++) ...{
object[] row = ...{"DEVID"+i,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),r.Next(1,1000) };
dataset.Tables[0].Rows.Add(แถว);
ถ้า (ผม % 300 == 0) ...{
sd.Update(ชุดข้อมูล.ตาราง[0]);
ชุดข้อมูล.ตาราง[0].ล้าง();
-
-
sd.Update(ชุดข้อมูล.ตาราง[0]);
ชุดข้อมูล.ตาราง[0].ล้าง();
sd.ทิ้ง();
ชุดข้อมูลทิ้ง();
conn.ปิด();
-
TimeSpan ts = DateTime.Now - เริ่มต้น;
MessageBox.Show("ts = " + ts.TotalMilliseconds);
สำหรับการทดสอบนี้ ฉันใช้เวลา 28 วินาทีในการแทรกข้อมูล 100,000 ชิ้น ประสิทธิภาพค่อนข้างน่าประทับใจ แต่สำหรับการอัปเดตเป็นชุดและตัวอย่างการค้นหาทั่วโลก บันทึกจะถูกกรอกลงในชุดข้อมูล จากนั้นแถวต่างๆ จะถูกแยกออกมา
หากต้องการอัปเดต ในส่วนการทดสอบของฉันที่มีข้อมูลจำนวนเล็กน้อย การกรอกข้อมูล 100,000 ชิ้นลงในชุดข้อมูลจะไม่ทำงานอีกต่อไป หากเป็นล้าน คุณต้องดำเนินการอย่างไรก่อนจึงจะสามารถบันทึกข้อมูลได้ รวมอยู่ใน DataSet? Medium กล่าวอีกนัยหนึ่ง ฉันต้องเลือกระเบียนใดเพื่อสืบค้นระเบียนเหล่านี้
ดังนั้นฉันจึงยังคงใช้ DataTable ว่างเพื่อเพิ่มบันทึกที่จะอัปเดต:
sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest โดยที่ 1=0", conn);
//เงื่อนไข 1=0 รับประกันตารางว่าง
sd.UpdateCommand = ใหม่ SqlCommand ("อัพเดตชุด CurrentTest 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;
สำหรับ(int i=0;i<300;i++){
-
dataset.Tables[0].Rows.Add(แถว);
-
sd.Update(ชุดข้อมูล.ตาราง[0]);
ลองอัปเดต 300 ระเบียนก่อน หากสำเร็จ ระบบจะอัปเดตระเบียนทั้งหมดในลูป แต่จะแจ้งว่าการดำเนินการแทรกจำเป็นต้องมี InsertCommand เนื่องจากเป็นตารางว่าง จากนั้นจึงเพิ่มการดำเนินการ RowState
หากการอัปเดตถูกส่งไปยังฐานข้อมูลในขณะนี้ การดำเนินการแทรกจะดำเนินการและไม่สามารถอัปเดตได้ เปลี่ยนเป็น:
สำหรับ(int i=0;i<300;i++){
-
แถว = {กรอกค่าเริ่มต้น};
dataset.Tables[0].Rows.Add(แถว);
-
ชุดข้อมูล.AcceptChanges();
สำหรับ(int i=0;i<300;i++){
-
dataset.Tables[0].Rows[i][x] = "xxxxxxx";
-
-
sd.Update(ชุดข้อมูล.ตาราง[0]);
ขั้นแรกให้แทรกข้อมูลลงใน DataTable จากนั้นใช้ AcceptChanges() เพื่อแก้ไข RowState เป็น UnChanged จากนั้นแก้ไขข้อมูลในตารางเพื่อเปลี่ยนสถานะ UnChanged
เปลี่ยน DataTable จากสถานะปัจจุบันเป็นต้นฉบับ จากนั้นอัปเดตแถวของ DataTable คุณสามารถใช้ได้
การอัปเดตสำเร็จแต่ไม่สะดวกจริงๆ
ปรับแนวคิด ขั้นแรกให้นำ 200 รายการจากฐานข้อมูล (ขนาดของการอัปเดตแบบแบตช์) และรับ Original DataTable โดยตรง
sd.SelectCommand = new SqlCommand("เลือก 200 อันดับแรก devid,data_time,data_value จาก CurrentTest", conn);
ชุดข้อมูล ชุดข้อมูล = ชุดข้อมูลใหม่ ();
sd.Fill(ชุดข้อมูล);
ใช้ช่องว่าง 200 ช่องเหล่านี้เพื่ออัปเดตข้อมูลอื่นๆ และดู:
สำหรับ (int i = 0; i < 100; i++)
-
dataset.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
ชุดข้อมูล.ตาราง[0].แถว[i].EndEdit();
-
sd.Update(ชุดข้อมูล.ตาราง[0]);
โอเค สำเร็จ 555 กรอกข้อมูลเพื่ออัพเดทในพื้นที่นี้ต่อไปแล้วส่งเมื่อเต็ม ด้วยวิธีนี้ ใช้เวลาเพียงไม่กี่รอบในการอัปเดตข้อมูล 100,000 ชิ้น
DateTime start = DateTime.Now;
การเชื่อมต่อสตริงString = "";
ใช้(SqlConnection conn = new SqlConnection(connectionString))...{
conn.เปิด();
SqlDataAdapter sd = SqlDataAdapter ใหม่();
sd.SelectCommand = new SqlCommand("เลือก 200 อันดับแรก devid,data_time,data_value จาก CurrentTest", conn);
ชุดข้อมูล ชุดข้อมูล = ชุดข้อมูลใหม่ ();
sd.Fill(ชุดข้อมูล);
สุ่ม r = สุ่มใหม่ (1,000);
sd.UpdateCommand = new SqlCommand("update CurrentTest "
+ " 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;
สำหรับ (จำนวน int = 0; นับ < 100,000;)
-
สำหรับ (int i = 0; i < 200; i++,count++)
-
dataset.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;
ชุดข้อมูล.ตาราง[0].แถว[i].EndEdit();
-
sd.Update(ชุดข้อมูล.ตาราง[0]);
-
ชุดข้อมูล.ตาราง[0].ล้าง();
sd.ทิ้ง();
ชุดข้อมูลทิ้ง
http://www.cnblogs.com/Seabiscuit/archive/2010/05/25/1743341.html