JdbcTemplate - queryForList - 对于大量数据运行缓慢

问题描述 投票:0回答:3

我正在使用 Spring Boot + CommonsDBCP + JdbcTemplate。我需要从具有大量数据的 Hive 表中获取记录。

SQL:

select * from customer

总记录:52K。

我正在使用 List> result = jdbcTemplate.queryForList(SQL) 来获取记录。对于上述数量的记录来说,运行速度很慢。

这使用 RowMapperResultSetExtractor 需要 96 秒 来提取数据。如果数据量增加,查询时间就会增加。

有什么建议可以改进这个时间或使用 jdbctemplate 中的任何其他方法吗?

jdbctemplate
3个回答
1
投票

您可以使用

SELECT a, b, c, ...
使用 try-with-resources 执行普通 JDBC,或者使用 ResultSetMetaData 给出列标签到列号。映射列表很昂贵,因此对象列表会更好。 RowSet 类有很多。

最后但并非最不重要的一点是,简单地收集列表,但迭代所有列表将是理想的选择。

本地内存减慢速度时的一个功能是使用

Statement#setMaxRows
setLargeMaxRows
来使用零件。

还有另一种选择:表转储。

无事务查询也可能有帮助。

这些都是有争议的措施;必须尝试一下。这是一个令人信服的改进,我可以在任何我从未发现过的地方重复使用。先从其他答案开始。


0
投票

如果您有一个可以映射到

customers
表的类,您可以尝试编写一个自定义
RowMapper
,将表中的条目映射到相关类的
List

List<Customer> customers = jdbcTemplate.query("SELECT * FROM customers", getRowMapper());//where getRowMapper` is a method that returns a relevant RowMapper

另一种选择是:

List<Customer> customers = jdbcTemplate.queryForList("SELECT * FROM customers", Customer.class);

但是后一个解决方案也将使用

RowMapperResultSetExtractor
,我相信仍然会缓慢地处理结果。

我确实记得在 Spring JDBC javadoc 中的某个地方读过一些内容,not使用自定义

RowMapper
是低效的,因为执行映射的相关类需要将结果与相关类进行比较,以确保列与相关的匹配。属性,这需要时间。


0
投票

一个。可能只用必需的列替换 select 子句

String sql = "SELECT * FROM customers" // old
String sql = "SELECT column1,column2... FROM customers" //new

两个。像这样使用 JdbcTeplate.query() 方法

    List<Customer> result = jdbcTemplate.query(sql, (rs, rowNum) ->
            new Customer(
                    rs.getLong("column1"),
                    rs.getDate("column2"),
                    ...
            ), new Object[]{<sql_params>});

三。消除获取瓶颈。

this.jdbcTemplate.setFetchSize(1000);

四。查看数据库端,分区的键、索引等是否就位?

五。 List>实际上做了什么,有多余的工作吗?

© www.soinside.com 2019 - 2024. All rights reserved.