2013-01-16 67 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