程式應用場景:
年初從總公司交接了一個評分系統,系統大概情況是80w考生,每個考生105條作答資料,作答資料主要是客觀題(單選題,多選題,判斷題),評分時間大概40分鐘左右。
需求:優化程式碼,提升評分效率,優化之後評分完成在20分鐘左右。
已有程式碼優化邏輯:
1.程式方面:
多執行緒,通過計算評分的人數,得到需要的執行緒數量,開啟執行緒分別進行評分
2.查詢資料:
成績表建立自增長Id,查詢匹配需要評分的資料用where id> =Start and id< End
3.插入資料:
採用DataTable資料匯入到Sql Server,提示評分完成時儲存資料效率
詳細說一下第二點的邏輯
假設資料庫有100w條需要評分的資料,這時通過計算大概得到需要開啟25個執行緒去同時進行評分,也就是說第一個執行緒去評分資料庫Id在 1~40000考生的資料,也就是說去查詢資料時,大概查詢語句select * from A where Id>=1 and Id<40000這樣能夠保證查詢出來得效率是最高的;
但是這裡會有缺陷,如果資料存在刪除過在插入肯定資料就不是連續的,也就是
where Id>=1 and Id<40000不能保證查詢得到40000條資料,資料庫表中存在的Id不一定是從1開始,所以目前這種查詢方式是很理想化的。後續這裡還需要在這快研究和學習下。
本次優化細節
程式碼片段1
優化前:
優化後:
總結:提取執行緒內查詢資料儲存到記憶體中,從而只會查詢一次。
程式碼片段2
優化前:
優化後:
總結:修改List集合取一條資料的方式,Where修改成Find,如果還需要在這裡提升查詢效率可以修改成for迴圈,但會導致程式碼可讀性會變差。
程式碼片段3
優化前
優化後
總結:修改DataTable表Select查詢方式,先儲存到Dictionary中,在通過Key去取對應的資料。
最後通過測試全部完成評分時間大概20分鐘左右,也算成功的完成了這個任務,可能還需要在研究研究程式碼,看能否有其他地方可以改善的。
存在的疑惑:
執行緒運算佔用的電腦Cpu的具體的值?
是否存在最佳執行緒數量?
電腦Cpu處理能力越強是否也能夠提升程式的評分效率?
總結:
1.執行緒裡反覆查詢而且不變的基礎資料放到執行緒外查詢儲存到變數中
2.List集合的Where查詢修改成Find查詢,極高的提升查詢效率
3.DataTable的Select改用Dictionary<string,DataRow[]>,同樣極高的提升查詢效率
這次能夠站在前人的肩膀上完成這一次程式碼的優化還有學習到了很多,瑾以寫在這片文章分享個人在平時工作中的解決的一些問題,希望這次能夠通過分享此篇文章讓自己更多的去記錄和分享工作中遇到以及解決的問題,提升自己的競爭力。