У меня есть подготовленное заявление в моей заявке, и для получения результатов требуется 3 минуты. Тем не менее, тот же запрос, который я выполнил в sql разработчику, и это займет всего менее 0,1 секунды, чтобы дать результаты. Я провел исследование по этому вопросу на протяжении всей прошлой недели и не смог найти правильного решения. Вот мой код.
public List<ResponseDto> loadData(RequestDto request) throws SQLException {
List<ResponseDto> responseDto = new ArrayList<>();
int sortBy = request.getSortBy();
String sql = "SELECT *" +
"FROM (SELECT r.*, ROWNUM RNUM, COUNT(*) OVER () RESULT_COUNT " +
" FROM (SELECT *" +
"FROM" +
" (SELECT r.VALUE_4," +
" r.DATE," +
" r.ID," +
" r.AMOUNT," +
" r.TO_AGENT_ID," +
" r.FROM_AGENT_ID," +
" a.NAME," +
" r.VALUE_2," +
" r.VALUE_1," +
" r.STATUS," +
" r.VALUE_3," +
" r.TEXT" +
" FROM MY_TABLE r" +
" INNER JOIN AGENT a " +
" ON a.AGENT_ID=r.TO_AGENT_ID" +
" WHERE r.STATUS = 1 " +
" AND r.ID IN" +
" (SELECT T.ID FROM TEST_TABLE T" +
" INNER JOIN AGENT af" +
" ON af.AGENT_ID = T.FROM_AGENT_ID " +
" INNER JOIN AGENT at" +
" ON at.AGENT_ID=T.TO_AGENT_ID" +
" WHERE T.FROM_AGENT_ID=?";
StringBuilder sbQuery = new StringBuilder(sql);
if (request.getToAgentId() != 0) {
sbQuery.append(" AND T.TO_AGENT_ID = ? ");
} else if (request.getQueryParam() != null && !request.getQueryParam().equalsIgnoreCase("")) {
sbQuery.append(" AND UPPER(at.NAME) like UPPER( ? ) ");
}
String secondPart =
" AND T.STATUS = 1" +
" AND TO_DATE(T.DATE) BETWEEN TO_DATE(?, 'yyyy-MM-dd') AND TO_DATE(?, 'yyyy-MM-dd')" +
" ) " +
" or r.VALUE_3=?";
sbQuery.append(secondPArt);
if (sortBy == 1) {
sbQuery.append(" ORDER BY a.NAME ");
} else if (sortBy == 2) {
sbQuery.append(" ORDER BY r.AMOUNT ");
} else if (sortBy == 3) {
sbQuery.append(" ORDER BY r.VALUE_4 ");
}
if (request.getSortingOrder() == 1) {
sbQuery.append("DESC ");
} else if (request.getSortingOrder() == 2) {
sbQuery.append("ASC ");
}
sbQuery.append(" )) R)" +
"WHERE RNUM between ? and ?");
String sqlq = sbQuery.toString();
log.info(sqlq);
try(Connection con = dataSource.getConnection(); PreparedStatement pstmt = con.prepareStatement(sbQuery.toString()) ) {
con.setAutoCommit(false);
String nameParam = "%" + request.getQueryParam() + "%";
pstmt.setLong(1, request.getFromAgentId());
if (request.getToAgentId() != 0) {
pstmt.setLong(2, request.getToAgentId());
} else if(request.getQueryParam() != null && !request.getQueryParam().equalsIgnoreCase("")) {
pstmt.setString(2, request.getQueryParam());
}
pstmt.setString(3, request.getFromDate());
pstmt.setString(4, request.getToDte());
pstmt.setString(5, request.getQueryParam());
pstmt.setLong(6, request.getFromIndex());
pstmt.setLong(7, request.getToIndex());
responseDto = helperMethod(pstmt);
con.commit();
} catch (SQLException e) {
log.error(e.getMessage());
throw e;
}
return responseDto;
}
public List<MyDto> helperMethod(PreparedStatement pstmt) throws SQLException {
List<MyDto> myDtoList = new ArrayList<>();
try( ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
MyDto myDto = new MyDto();
myDto.setValue4(rs.getLong("VALUE_4"));
myDto.setDate(rs.getDate("DATE"));
myDto.setTransactionId(rs.getLong("ID"));
myDto.setAmount(rs.getLong("AMOUNT"));
myDto.setToAgentId(rs.getLong("TO_AGENT_ID"));
myDto.setFromAgentId(rs.getLong("FROM_AGENT_ID"));
myDto.setName(rs.getString("NAME"));
myDto.setValue2(rs.getLong("VALUE_2"));
myDto.setValue1(rs.getLong("VALUE_1"));
myDto.setStatus(rs.getInt("STATUS"));
myDto.setValue3(rs.getString("VALUE_3"));
myDto.setText(rs.getString("TEXT"));
myDtoList.add(myDto);
}
}catch (Exception ex){
log.error(ex.getMessage());
throw ex;
}
return myDtoList;
}
Как я уже сказал, тот же запрос работает в миллисекундах. Я действительно не знаю, что я делаю здесь неправильно.
Любая помощь будет благодарна!