標籤:
前幾天做一個批量發訊息的功能,因為要向訊息表中批量寫入資料,用的EF架構的插入方法;不用不知道,一用嚇一跳;就10000條資料就耗時好幾分鐘,對應追求使用者體驗的我來說這是極不能容忍的,後來改為拼接SQL,效能提高了好幾倍;現在來分享一下經驗:
原始的方法類似這種:
1 public ActionResult Add(ItemDetails entity) 2 { 3 var sw = new Stopwatch(); 4 sw.Start(); 5 using (db) 6 { 7 for (var i = 0; i < 10000; i++) 8 { 9 db.ItemDetails.Add(entity);10 db.SaveChanges();11 }12 }13 sw.Stop();14 var date = sw.Elapsed;15 return Json(string.Format("總耗時:{0}", date));16 }
來看看添加10000條資料耗時:
就10000條資料就耗時這麼久,要是上百萬的資料量,那簡直就不能想象,再來看看最佳化後的:
產生SQL的方法:
1 public class ItemDetailBatch 2 { 3 public static string BatchAdd(ItemDetails entity) 4 { 5 SqlParameter [] paras= 6 { 7 new SqlParameter("@Item_Name",SqlDbType.VarChar,100), 8 new SqlParameter("@Item_Price",SqlDbType.Int), 9 new SqlParameter("@Image_Name",SqlDbType.VarChar,100), 10 new SqlParameter("@Description",SqlDbType.VarChar,100),11 new SqlParameter("@AddedBy",SqlDbType.VarChar,100)12 };13 paras[0] .Value= entity.Item_Name;14 paras[1].Value = entity.Item_Price;15 paras[2].Value = entity.Image_Name;16 paras[3].Value = entity.Description;17 paras[4].Value = entity.AddedBy;18 var sb=new StringBuilder();19 sb.Append("insert into ItemDetails (Item_Name,Item_Price,Image_Name,Description,AddedBy) ");20 sb.AppendFormat("values (‘{0}‘,{1},‘{2}‘,‘{3}‘,‘{4}‘)", paras[0].Value, paras[1].Value, paras[2].Value,paras[3].Value, paras[4].Value);21 return sb.ToString();22 }23 }
Controller層調用:
1 public ActionResult Add(ItemDetails entity) 2 { 3 var sw = new Stopwatch(); 4 sw.Start(); 5 using (var db = new ShoppingDBConn()) 6 { 7 var sql = new StringBuilder(); 8 for (int i = 0; i < 10000; i++) 9 {10 //產生SQL11 sql.Append(ItemDetailBatch.BatchAdd(entity));12 }13 //一次性執行SQL14 db.Database.ExecuteSqlCommand(sql.ToString());15 }16 sw.Stop();17 var date = sw.Elapsed;18 return Json(string.Format("總耗時:{0}", date));19 }
介面資料:
同樣10000條總耗時:
EF沒添加一次都要向資料庫提交一次,而直接拼接SQL的方法就是減少與資料庫的互動次數,一次性提交執行所有資料;
EF大資料大量新增效能問題