摘要:Java setFetchSize,撈大量資料差異測試
因為工作上遇到撈十萬筆時花太多時間的問題,而追根究底,找到了這篇文章
http://benjchristensen.com/2008/05/27/mysql-jdbc-memory-usage-on-large-resultset/
然後實機測試差異狀況
而整理了一張表,看一下有加setFetchSize與沒有加setFetchSize到底差了多少
Time(ms) | Memory(KB) | Total Time | Total Memory | 包含GC後 | |||
setFetchSize | Query | Next | Query | Next | (ms) | (KB) | Time |
Y | 3 | 229 | 4 | 7128 | 232 | 7132 | 263 |
Y | 4 | 293 | 260 | 9816 | 297 | 10076 | 326 |
Y | 5 | 227 | 40 | 8244 | 232 | 8284 | 265 |
N | 210 | 48 | 24292 | 600 | 258 | 24892 | 365 |
N | 220 | 52 | 20580 | 1344 | 272 | 21924 | 385 |
N | 228 | 51 | 20972 | 3188 | 279 | 24160 | 385 |
有設setFetchSize的話,則一開始的Query就會很快,而且資料是一筆一筆撈取,就不會一開始耗了大量的記憶體資料
這兩者的差異,雖然總total時間是差不多的,但由於memory的消化,差了快一倍以上,
而memory又是影響效能的關鍵,由於資料越跑越多,而記憶體狀況越來越差,而導致會經常性的GC垃圾記憶體回收,而回收會佔用一些時間。
這兩者的差異,差了快一百毫秒的時間,如果還有一堆的程式要跑,那這差異,就越來越重要,記憶體不足,會使總total時間不斷的變動
Java撈取可用記憶體方式
public long getUsedMemory()
{
int kb = 1024;
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize()) / kb;
return usedMemory;
}
Java 撈取資料方式
try {
pstmt = conn.prepareStatement(sql);
pstmt.setFetchSize(Integer.MIN_VALUE);
rs = pstmt.executeQuery();
while(rs.next())
{
n++;
}
}
catch(Exception ex)
{
log.error(ex);
ex.printStackTrace();
} finally {
rs.close();
pstmt.close();
conn.close();
}