Java连MySQL性能调优(batch insert和连续left join筛选)
之前一個(gè)數(shù)據(jù)校驗(yàn)功能遇到嚴(yán)重性能瓶頸
插入數(shù)據(jù)居然需要22秒,優(yōu)化后0.38秒
一個(gè)聯(lián)合join校驗(yàn)需要42秒,優(yōu)化后1.87秒
一個(gè)增刪改對(duì)比顯示union的sql需要49秒,優(yōu)化后1.023秒
1、首先是batch的問(wèn)題:
在本項(xiàng)目中,使用了org.springframework.jdbc.core.JdbcTemplate類作為數(shù)據(jù)庫(kù)鏈接服務(wù)。批量插入時(shí),調(diào)用jdbcTemplate.batchUpdate方法進(jìn)行批量插入,然而插入速度不盡如人意,非常緩慢。問(wèn)題點(diǎn)在于,明明使用了batchUpdate而不是逐條插入,為何會(huì)出現(xiàn)插入緩慢的問(wèn)題呢?
原來(lái)在鏈接MySQL的時(shí)候,并沒(méi)有設(shè)置自動(dòng)合并多個(gè)insert的功能,導(dǎo)致還是變成了逐條插入。正確的方式是,修改MySQL鏈接參數(shù),添加關(guān)鍵字段rewriteBatchedStatements=true,詳細(xì)如下:
jdbc:mysql://test_host:3306/test_schemas1?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&rewriteBatchedStatements=true
添加這個(gè)rewriteBatchedStatements參數(shù)設(shè)置后,batch插入從原來(lái)的22秒變成了0.38秒,速度提升明顯。
2、接著是一個(gè)聯(lián)合join的校驗(yàn)問(wèn)題。
項(xiàng)目需求一個(gè)3表join,以左表為基準(zhǔn),進(jìn)行2次連續(xù)的left join且附帶篩選條件。調(diào)優(yōu)前運(yùn)行緩慢,需要44秒。
原先采用一條sql解決所有問(wèn)題,后改為首先用3條sql將3個(gè)表的最新記錄篩選下來(lái),再用Map<String, List<String> >數(shù)據(jù)結(jié)構(gòu)記錄key和重復(fù)的項(xiàng),遍歷進(jìn)行java式的join,由于全部運(yùn)算基于hashmap且在內(nèi)存中運(yùn)行,速度非常快
調(diào)優(yōu)后速度變?yōu)?.87秒
3、最后是個(gè)增刪改對(duì)比顯示的sql問(wèn)題
這段SQL的原來(lái)思路是先left join,右表為null的就是相對(duì)右表新增的;再inner join,把對(duì)比修改的字段都判斷一遍,不全相等的就是左表相對(duì)右表更改的;最后再right join,把左表為null的篩出來(lái),說(shuō)明這是左表相對(duì)右表刪除的。最后最后,把3個(gè)查出來(lái)的結(jié)果再union起來(lái)。整個(gè)查詢時(shí)間非常漫長(zhǎng),需要49秒。
優(yōu)化后的代碼,將左表和右表分別用DAO載下來(lái),然后通過(guò)HashMap來(lái)進(jìn)行對(duì)比,大致代碼如下:
Map<String, String[]> mapA = dbData; Map<String, String[]> mapB = upload; Map<String, String[]> mapBadd = new HashMap<String, String[]>(mapB); Map<String, String[]> mapBdel = new HashMap<String, String[]>(); Map<String, String[]> mapBchange = new HashMap<String, String[]>(); Iterator<String> it = mapA.keySet().iterator();while (it.hasNext()) { String key = it.next(); String[] val = mapA.get(key); if (mapB.containsKey(key)) { String[] bVal = mapB.get(key); if (val != null && val.equals(bVal) || Arrays.equals(val, bVal)) { } else { String[] changeVal = new String[val.length + bVal.length]; System.arraycopy(val, 0, changeVal, 0, val.length); System.arraycopy(bVal, 0, changeVal, val.length, bVal.length); mapBchange.put(key, changeVal); } mapBadd.remove(key); } else { // A里面有的,B沒(méi)有的 mapBdel.put(key, val); } }
優(yōu)化后僅需要1.023秒,非常快。
總結(jié)
以上是生活随笔為你收集整理的Java连MySQL性能调优(batch insert和连续left join筛选)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java反射在整个程序运行中的位置
- 下一篇: Django 框架14: 缓存