*)問題背景:
從大數據量的表中,查出數據,做邏輯處理,之后,再更新回數據庫。
出現的問題:更新數據庫的時候,為了減少連接數據庫的次數,在mybatis里用<foreach>標簽循環拼接了update語句。在執行這個update的時候,鎖表了(mysql數據庫)。
為了解決鎖表,在update的字段上加了索引,這樣就不會整個表鎖了,就算鎖也是行鎖。
但是仍然會出現數據庫連接超時,和更新速度特別慢的情況。前端頁面遲遲拿不到更新結果。
試着去解決的方法:
上網查優化update SQL語句的方法,試圖通過優化SQL來改善:將有點復雜的SQL優化到比較簡單,之后,效果仍不明顯。
*)解決方法:
①將這個操作開一個多線程,然后前端頁面顯示個下拉框,顯示更新多少條剩余多少條。這樣不影響前端的顯示,異步進行。
②發現慢的原因是:當時查詢出錯了,而且當時邏輯處理里面,用的2個for循環嵌套效率太慢,前端請求都斷了。(也就是速度慢不僅僅是update語句的問題,邏輯處理的速率也太慢了)
所以,改進內容是:
多線程里做的事:把兩個表的數據分別查詢出來,得到兩個集合,再把兩個集合分別轉成map ,兩個表關聯的字段作為map的key建對比得到一個新的集合(cList)(之前是把2個表的數據查出來,通過for循環再轉換成一個list的,耗內存耗時間),再去把clist每2000條為一批循環更新(分批更新,防止過多的量造成數據庫連接斷開。之前是把clist一起批量更新了。但是以后數據量大了這個慢還是解決不了,這只能治個標)。
*)問題總結:
1.for循環分開為兩個查詢,減少內存消耗
2.轉換成map,加快匹配速度
3.單獨開線程,異步減少前端等待頁面的時間
4.分批更新,減少行鎖的可能,減少數據庫占用時間