我正在使用 Spring Boot + CommonsDBCP + JdbcTemplate。我需要从具有大量数据的 Hive 表中获取记录。
SQL:
select * from customer
总记录:52K。
我正在使用 List 来获取记录。对于上述数量的记录来说,运行速度很慢。
这使用 RowMapperResultSetExtractor 需要 96 秒 来提取数据。如果数据量增加,查询时间就会增加。
有什么建议可以改进这个时间或使用 jdbctemplate 中的任何其他方法吗?
您可以使用
SELECT a, b, c, ...
使用 try-with-resources 执行普通 JDBC,或者使用 ResultSetMetaData 给出列标签到列号。映射列表很昂贵,因此对象列表会更好。 RowSet 类有很多。
最后但并非最不重要的一点是,简单地不收集列表,但迭代所有列表将是理想的选择。
本地内存减慢速度时的一个功能是使用
Statement#setMaxRows
或 setLargeMaxRows
来使用零件。
还有另一种选择:表转储。
无事务查询也可能有帮助。
这些都是有争议的措施;必须尝试一下。这是一个令人信服的改进,我可以在任何我从未发现过的地方重复使用。先从其他答案开始。
如果您有一个可以映射到
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
是低效的,因为执行映射的相关类需要将结果与相关类进行比较,以确保列与相关的匹配。属性,这需要时间。
一个。可能只用必需的列替换 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