Java setFetchSize,撈大量資料差異測試

摘要: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();
        }