2013-01-16 119 views
0

我想從我的Java程序中的Oracle 10g中讀取數據,其中一列是CLOB類型,如下所示(注意:數據是CLOB類型的列):從Oracle 10g獲取Clob導致高CPU使用率

private final static String LOAD_QUERY 
     = "SELECT id, data FROM table WHERE id = ?"; 

    public SomeObject loadById(long id){ 
     SomeObject obj = null; 
     try { 
      obj = jdbcTemplate.queryForObject(LOAD_QUERY, 
        new ParameterizedRowMapper<SomeObject>() { 
       public Model mapRow(ResultSet rs, int rowNum) throws SQLException { 
        long id = rs.getLong("id"); 
        String data = rs.getString("data"); 
        return new SomeObject(id, data); 
       } 
      }, id); 
     } catch (Exception e) { 
      throw new SomeException("Error during SQL query", ErrorCode.INTERNAL_ERROR, e); 
     } 
     return obj; 
    } 

存儲在CLOB中的數據大小高達44Mb。我能夠成功檢索CLOB值,但它對CPU使用率造成很大影響。在使用Java VisualVM運行分析器之後,它看起來像是一個IO問題。我應該如何解決這個問題?提前致謝!

+1

你能定義「大熱門」嗎?你在說毫秒嗎?秒?分鐘?你說它正在產生大量的CPU使用率。那是在數據庫服務器上嗎?或者在應用程序服務器上?然後你說這看起來像是一個I/O問題。你如何從CPU問題到I/O問題?如果這是一個I/O問題,那麼當分析代碼時,您會發現很多I/O等待,而不是很多CPU等待。 –

+0

讀取CLOB數據需要幾秒鐘的時間。在閱讀過程中,CPU使用率達到50%左右。當我用java分析器檢查它時,大部分cpu時間都花在java.net.SocketInputStream.read()上。 – user1985101

+0

我猜你所說的CPU峯值位於應用程序服務器上,對嗎?如果通過網絡從數據庫服務器嚮應用程序服務器推送44 MB數據,則幾秒鐘內似乎很合理。假設網絡上沒有其他流量,那麼通過100baseT以太網網絡傳輸大量數據需要4秒多一點的時間。所以你使用一半的CPU來跟上網卡的事實對我來說似乎很合理。是否有理由希望能夠更快地傳輸數據? –

回答

0

如果它是一個大clob,我建議嘗試通過一個流檢索內容。 通過使用getString,可以分配一個大型數組,也可以是由二級緩存分配的大型數組,甚至可以分配多個數組,而通過底層框架的不同層複製值。 所有這些字符串分配和複製都會導致較高的CPU使用率。

+0

我已經嘗試使用InputStream並將CLOB數據檢索爲字節數組,並在我的程序中進行字符串轉換。然而,當我用java分析器檢查它時,瓶頸發生在java.net.SocketInputStream.read()上。 – user1985101

+0

這意味着它等待數據來自數據庫。如果數據流緩慢,它仍會盡可能多地使用cpu,就像它快速到來一樣。需要看看優化數據庫端的流/ clob。也許你可以gzip clob字段的內容。 – Solubris

+0

是的,我已經嘗試使用gzip進行壓縮,並在將巨大數據存儲到數據庫之前利用mime編碼。在我的實驗中,它確實表明正在傳輸的數據量越小,所消耗的CPU時間就越少。從你的經驗來看,如果我從blob versue clob類型的列讀取大數據,性能差異是什麼? – user1985101