3

我的问题是:我试图通过来自 MySQL 的 JDBCTemplate 在 Spring 中处理大约 150 万行数据。有了这么多的行,我正在使用这里建议的 RowCallbackHandler 类

代码实际上可以工作,但是速度很慢......问题是,无论我将提取大小设置为什么,每次提取我似乎都能获得大约 350 条记录,提取之间有 2 到 3 秒的延迟(来自观察我的日志) . 我尝试注释掉 store 命令并确认行为保持不变,所以问题不在于写入。

有 6 列,只有 1 列是 varchar,而那一列只有 25 个字符长,所以我看不出吞吐量是问题。

理想情况下,我希望一次获得更多的 30000-50000 行。有没有办法做到这一点?

这是我的代码:


    protected void runCallback(String query, Map params, int fetchSize, RowCallbackHandler rch) 
            throws DatabaseException {
        int oldFetchSize = getJdbcTemplate().getFetchSize();
        if (fetchSize > 0) {
            getJdbcTemplate().setFetchSize(fetchSize);
        }
        try {
            getJdbcTemplate().query(getSql(query), rch);
        }
        catch (DataAccessException ex) {
            logger.error(ExceptionUtils.getStackTrace(ex));
            throw new DatabaseException( ex.getMessage() );         
        }
        getJdbcTemplate().setFetchSize(oldFetchSize);
    }

and the handler:

public class SaveUserFolderStatesCallback implements RowCallbackHandler {
        @Override
        public void processRow(ResultSet rs) throws SQLException {
            //Save each row sequentially.
            //Do NOT call ResultSet.next() !!!!

            Calendar asOf = Calendar.getInstance();
            log.info("AS OF DATE: " + asOf.getTime());
            Long x = (Long) rs.getLong("x");
            Long xx = (Long) rs.getLong("xx");
            String xxx = (String) rs.getString("xxx");
            BigDecimal xxxx = (BigDecimal)rs.getBigDecimal("xxxx");
            Double xxxx = (budgetAmountBD == null) ? 0.0 : budgetAmountBD.doubleValue();
            BigDecimal xxxxx = (BigDecimal)rs.getBigDecimal("xxxxx");
            Double xxxxx = (actualAmountBD == null) ? 0.0 : actualAmountBD.doubleValue();           

            dbstore(x, xx, xxx, xxxx, xxxxx, asOf);
        }       

    }
4

3 回答 3

0

你的查询是什么?尝试为您正在搜索/排序的字段创建 indexex。这会有所帮助。

策略二:在内存缓存中实现。或者使用休眠加二级缓存。

这两种技术都可以显着加快您的查询执行速度。

于 2012-05-08T17:49:11.743 回答
0

几个问题

  1. 如果直接查询数据库需要多长时间。另一个问题可能是应用程序和数据库主机之间的 ASYNC_NETWORK_IO 延迟。

  2. 你没有使用Spring检查过吗

于 2012-05-08T17:49:40.870 回答
0

答案实际上是执行 setFetchSize(Integer.MIN_VALUE) 虽然这完全违反了 Statement.setFetchSize 的规定合同,mysql java 连接器使用这个值来流式传输结果集。这会带来巨大的性能提升。

修复的另一部分是我还需要创建自己的 (Spring) JdbcTemplate 子类,以适应负提取大小...实际上,我在这里举了代码示例,在那里我首先找到了设置 fetchSize(Integer .MIN_VALUE)

http://javasplitter.blogspot.com/2009/10/pimp-ma-jdbc-resultset.html

谢谢你们的帮助!

于 2012-05-09T13:43:02.877 回答