有二個表.表BOM資料量非常大.現是400W左右.表二PnoStatus資料不大.現只有50條左右.
都是自增主鍵.表BOM主鍵為IDNO,相關列有Pno(這個每Pno可能有3000多個相同的.),ldate(為資料插入時自動取當取時間).
表PnoStatus有主建ID,相關列有Pno,UpdateTime,Status.
表BOM每隔一個小時都會匯入新資料(每次大約3000條,相同pno).因相關要求.匯入時更新相關表PnoStatus.
規則就是在PnoStatus的Pno等於BOM的pno取最大ldata.然後比較PnoStatus的UpdateTime,後更新Status.
最開始,按語意自然如下處理.
db.PnoStatus.ToList().ForEach(t => { var maxdate = db.BOM.Where(p => p.PNo == t.Pno) .Max(p => p.ldate); if (t.UpdateTime > mdate) t.Status = "Blue"; else t.Status = "Red"; });
這樣處理後發現整個處理完要完時間8分鐘左右.現暫時還不影響.但是PnoStatus資料變多後恐出問題.
先查看這個語句.
select max(a.ldate) from BOM as a where a.PNo = 'Sdf00000001'
這條資料處理就要求10S左右.50條語句就500S.差不多是時間8分鐘.
結合前幾天看的HashTable的原理.我自己推斷如下.索引尋找和表的資料多少沒有關係都是O(1)次尋找.我先在表Bom
上想建立關於PNo的索引.那想給出相關錯誤.沒有成功.
最後我在預設索引上IDNO上想辦法.想尋找對應Pno的最大時間.而時間和IDNO有個明顯關係.IDNO越大.時間只會更大.不會更少.(表
BOM不會編輯資料,只會匯入資料.)寫出如下SQL.
select ldate from BOM where IDNO = (select max(IDNO) from BOM as a where a.PNo = 'Sdf00000001')
說實話.我剛寫出來沒想有什麼效果.在我認為這完全是把簡單問題複雜化了.但是我執行了下.顯示1S!!
相應的現在整個時間44S就全部完成.
對應過程:
可以看到第二個查詢SQL還進行了平行處理都要12S.而第一個雖然複雜.但是時間短.
整個過程自己都還相對不是很明白.感覺有很大的巧合性.SQL也不是我的專長.唯一肯定索引相對平常尋找優勢太明顯.希望給園友一點參考.
幾天后.我感到還是有點疑惑.試了如下二語句.
select max(IDNO) from BOM as a where a.PNo = 'Sdf00000001'select IDNO from BOM as a where a.PNo = 'Sdf00000001'
發現第二條語句也還是10S左右,沒有什麼區別.分析插入資料時.ldate插入時都是一樣.而IDNO是自增的不一樣.就這點而導致二條語句取Max(IDNO OR ldate)是產生10倍差.
原先在我想法中.取Max(IDNO)的值時會先把所有的IDNO取出來的再比較也是錯誤的.
他取Max(IDNO)時應沒有取出相關的IDNO而得到最大值.不過有個新的問題出來了.他是如何取最大值的?
可惜我不知道是否相關工具能查看到具體過程.希望有相關高手能提示下.