我意识到,当我执行一个使用JdbcTemplace.query()返回许多记录的简单选择时,数百个选择正在后台执行。 实际上每行一个,由于某些用户在ACL表中的记录数量很多,最终导致性能问题。
private final String PERMISSIONS_QUERY = "SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = :userId ";
private NamedParameterJdbcTemplate jdbcTemplate;
MapSqlParameterSource params = new MapSqlParameterSource(DAOConstants.USER_ID_KEY, userId);
List<UserPermissionRow> userPermissions = jdbcTemplate.query(PERMISSIONS_QUERY, params,
new RowMapper<UserPermissionRow>() {
@Override
public UserPermissionRow mapRow(ResultSet rs, int rowNum) throws SQLException {
return new UserPermissionRow(rs.getString(1), rs.getString(2));
}
});
我查看了显示正在执行的查询的P6Spy日志。如您所见,一个查询是按行执行的(我认为效率不高)。
READ
1566811816536|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10078, PERMISSION =
READ
1566811816536|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10079, PERMISSION =
READ
1566811816536|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10080, PERMISSION =
READ
1566811816536|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10081, PERMISSION =
READ
1566811816536|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10082, PERMISSION =
READ
1566811816536|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10083, PERMISSION =
READ
1566811816538|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10084, PERMISSION =
READ
1566811816538|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10085, PERMISSION =
READ
1566811816538|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10086, PERMISSION =
READ
1566811816538|-1||resultset|SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = '11582' |USER_ID = 10087, PERMISSION = READ
...
..
.
我想知道是否有一种更有效的方法,只需选择一个DB就可以检索如此大量的数据。
非常感谢您的反馈。
问题中原始方法的响应时间为5726毫秒。
请参阅以下我尝试的替代方法。 不幸的是,总体时机并没有改善。
选项1(声明)
Statement stmt = dataSource.getConnection().createStatement();
ResultSet rs = stmt.executeQuery(EXPERT_ACCESS_QUERY_2 + userId);
List<UserPermissionTest> list =new ArrayList<UserPermissionTest>();
// ============= Expert Access Query RAW: 79 ms
while(rs.next()){
UserPermissionTest e=new UserPermissionTest();
e.setIdentity(rs.getString(1));
e.setPermission(rs.getString(2));
list.add(e);
}
// ============ 5554 ms
选项2(ResultSetExtractor)
List <UserPermissionTest> userPerms = jdbcTemplate.query(EXPERT_ACCESS_QUERY_2 + userId,
new ResultSetExtractor<List<UserPermissionTest>>(){
@Override
public List<UserPermissionTest> extractData(ResultSet rs) throws SQLException, DataAccessException {
List<UserPermissionTest> list =new ArrayList<UserPermissionTest>();
while(rs.next()){
UserPermissionTest e=new UserPermissionTest();
e.setIdentity(rs.getString(1));
e.setPermission(rs.getString(2));
list.add(e);
}
return list;
}
});
//========= 5694 ms
答案 0 :(得分:1)
也许是因为您在下面的sql脚本中使用单个userId:
private final String PERMISSIONS_QUERY = "SELECT acl.user_id, acl.permission FROM v_user_acls acl WHERE acl.principal = :userId ";
尝试使用IN并在您的where条件下将userID列表用作参数?
我找到了此参考资料是否可以帮助您: https://www.technicalkeeda.com/spring-tutorials/spring-jdbctemplate-in-clause-example
答案 1 :(得分:0)
谢谢。就像Andreas所报告的那样,日志实际上并不是对数据库的调用,而是每次迭代中记录的结果集。 我发现提高性能的唯一解决方案是使用DB View来提高其性能。抱歉造成混乱。