需求:
從數據庫中取出一批數據,比如數據上限是20萬,現在要對其進行處理,用多線程分批處理。
(數據所在表的主鍵id是遞增的【分片數據庫自定義的主鍵自增函數】)
難點:如何從數據庫中分批讀取數據,每批之間又無重復數據
思路1:
用分頁查詢的方式取
先查詢出要處理的總數據量 count,然后假設每批要處理1000條,
int size = 1000; int threadNum = count / size + 1; for (int i = 0; i < threadNum; i++) { Map paramMap = new HashMap(); //分批查詢 paramMap.put("PAGE_INDEX", i*size); paramMap.put("PAGE_SIZE", size); //用 paramMap 去分頁查詢數據庫 }
【
好處是:每一批數據基本都是數量相同的(除了最后一批)。
缺點是:
需要計算分頁,查詢時還要排序,同時在整個取數據的過程中:
1、不能對每批獲取數據時的條件字段進行更新操作
2、不能對數據記錄進行刪除、增加操作】
思路2:
用取模的方式取數據
int size = 1000; int threadNum = count / size + 1; for (int i = 0; i < threadNum; i++) { Map paramMap = new HashMap(); //分批查詢 paramMap.put("threadNum", threadNum); paramMap.put("mod", i); //用 paramMap 去取模查詢數據庫
// SELECT * FROM `tableName` WHERE id % threadNum = mod ; 即查詢條件為 自增主鍵除以線程數余數為當前遍歷到的 i
}
【
好處是:
查詢時無需分頁、排序所以速度快,
在整個取數據過程中,
1、在一定程度上可以對每批查詢條件字段進行更新;
2、可以對數據記錄進行刪除操作
缺點是:主鍵必須相對連續、每批數據數量可能有很大誤差(如果主鍵不完全連續,比如做過刪除操作,或者查詢條件不同)】