我的问题是这样的:我试图通过来自MySQL的JDBCTemplate在Spring中处理大约150万行数据。如此大量的行,我正在使用RowCallbackHandler类建议here
代码实际上正在工作,但是很慢......问题是,无论我将提取大小设置为什么,我似乎每次获取大约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);
}
}
答案 0 :(得分:0)
你的查询是什么?尝试为要搜索/排序的字段创建indexex。这会有所帮助。
第二个策略:在内存缓存实现中。或者使用hibernate加上二级缓存。
这两种技术都可以显着加快查询执行速度。
答案 1 :(得分:0)
几个问题
直接查询数据包需要多长时间。另一个问题可能是应用程序和数据库主机之间的ASYNC_NETWORK_IO延迟。
您是否在不使用Spring
答案 2 :(得分: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
谢谢你们的帮助!