性能測試階段,預先插入一批數據到Mysql中。並分爲三個階段。html
第一階段:向Mysql的三張表裏,插入有關聯關係的18萬+18 * 3萬+18 * 4萬的數據。java
第二階段:插入第一階段數據量5倍的數據,即90萬爲基數sql
第三階段;插入第一階段數據量10倍的數據即180萬爲基數數據庫
方法1:本地JDBC插入。List<?>有1+3+4,共8個List<?>安全
方法1的問題有兩點: 1.JDBC順序執行效率很低 2.大數據量下,耗時會超過鏈接時間,致使鏈接超時。
方法2:本地或服務器端啓動多個任務將基礎數據List<?>插入。其餘的關聯數據,先檢索基礎數據List<?>,再將生成的關聯數據插入。服務器
將其他的7個List<?>作成7個類,在服務器上分別啓動。 方法2的優勢: 1.效率快,先插入基礎數據後,時間複雜度O,其他數據數據並行插入。時間總共O*2; 可是在實際執行狀況下,第一階段和第二階段都順利執行。可是第三階段卻暴露了問題。 方法2的問題: 1.7個任務,將180萬*7的數據檢索到內存後,內存溢出(OutOfMemoryError)。(下班開了任務就走的我,次日看日誌,瞬間淚流滿面)
鑑於方法2的問題,就在方法1的基礎上,作了修改。 方法一也有優勢,就是數據都在內存中,關聯數據的生成比較方便。不須要再去檢索數據庫,再額外佔用內存。方法三在此優勢上修改 方法3:基礎數據和關聯數據生成後,開啓多線程插入數據。8個List<?>就分8個線程插入。提高效率。多線程
方法3暴露的問題:(也許此方法暴露的不是問題,而是個人智商) 問題以下: 1.程序改成多線程後,對應的List<?>沒有改動。ArrayList<?>是線程非安全的。java.util.ConcurrentModificationException 2.線程的建立,阻塞,銷燬。多線程(ExecutorService service = Executors.newFixedThreadPool(8);)的使用 線程安全的類: CopyOnWriteArrayList<?> 參考資料(https://blog.csdn.net/liyu121/article/details/87873858)與(https://www.cnblogs.com/dolphin0520/p/3938914.html) CocurrentHashMap<key,value> (https://blog.csdn.net/fwt336/article/details/81110760) List<String> list = Collections.synchronizedList(new LinkedList<String>());(很low啊) 將LinkedList所有換成ConcurrentLinkedQueue(沒用過)
最終被智商戰勝的我(阻塞處理很差,致使的鏈接提早關閉沒有解決)選擇了方法4性能
方法4:在方法2的基礎上,將檢索條件改成按id檢索。並實現了可配置。 配置文件中,檢索id爲0-10000,而後7個任務並行,先檢索0-10000,插入。 修改配置文件,檢索id爲10001-20000...以此類推。解決了內存不足的問題。測試