진술이란 무엇입니까?setFetchSize(nSize) 메서드가 SQL Server JDBC 드라이버에서 실제로 수행됩니까?
저는 매일 수백만 개의 레코드가 있는 정말 큰 테이블을 가지고 있습니다. 그리고 매일 마지막에 저는 전날의 모든 레코드를 추출하고 있습니다.다음과 같은 작업을 수행합니다.
String SQL = "select col1, col2, coln from mytable where timecol = yesterday";
Statement.executeQuery(SQL);
문제는 이 프로그램이 메모리의 모든 결과를 가져온 다음 처리하기 때문에 2GB의 메모리를 사용한다는 것입니다.
는 설을시습다니했도정▁the다▁setting니를 설정해 보았습니다.Statement.setFetchSize(10)
하지만 OS와 동일한 메모리를 사용하면 아무런 차이가 없습니다.이를 위해 Microsoft SQL Server 2005 JDBC Driver를 사용하고 있습니다.
쿼리를 실행하여 몇 개의 행만 표시하고 아래로 스크롤하면 더 많은 결과가 표시되는 경우처럼 Oracle 데이터베이스 드라이버처럼 작은 청크로 결과를 읽을 수 있는 방법이 있습니까?
JDBC는setFetchSize(int)
메소드는 JVM에서 데이터베이스로 전송되는 네트워크 호출의 수와 그에 상응하는 ResultSet 처리에 사용되는 RAM의 양을 제어하기 때문에 JVM 내의 성능 및 메모리 관리에 매우 중요합니다.
기본적으로 setFetchSize(10)가 호출되고 드라이버가 이를 무시하는 경우 두 가지 옵션만 있을 수 있습니다.
- 가져오기 크기 힌트를 지원하는 다른 JDBC 드라이버를 사용해 보십시오.
- Connection에서 드라이버별 속성(Connection 인스턴스를 만들 때 URL 및/또는 속성 맵)을 확인합니다.
RESULT-SET는 쿼리에 대한 응답으로 DB에 저장된 행 수입니다.ROW-SET는 JVM에서 DB로 호출할 때마다 RESULT-SET에서 가져온 행의 청크입니다.처리에 필요한 이러한 호출 수와 결과 RAM은 가져오기 크기 설정에 따라 달라집니다.
따라서 RESULT-SET에 100개의 행이 있고 fetch-size가 10개인 경우 약 10*{row-content-size}개의 RAM을 사용하여 모든 데이터를 검색하는 네트워크 호출이 10개가 됩니다.
기본 fetch-size는 10으로 다소 작습니다.게시된 경우 드라이버가 페치 크기 설정을 무시하여 한 번의 호출로 모든 데이터를 검색하는 것처럼 보입니다(대용량 RAM 요구 사항, 최적 최소 네트워크 호출).
일들는나어 아래에서 일.ResultSet.next()
한 한것이 입니다.(로컬) ROW-SET에서 이를 가져오고 로컬 클라이언트에서 사용이 완료될 때 서버에서 (보이지 않게) 다음 ROW-SET를 가져옵니다.
설정은 '힌트'에 불과하기 때문에 이 모든 것은 드라이버에 따라 다르지만 실제로는 이것이 많은 드라이버와 데이터베이스(Oracle, DB2 및 MySQL의 많은 버전에서 확인됨)에서 작동하는 방식이라는 것을 알게 되었습니다.
그fetchSize
매개 변수는 데이터베이스에서 한 번에 가져올 많은 행에 대한 JDBC 드라이버에 대한 힌트입니다.하지만 운전자는 이를 무시하고 적합하다고 판단되는 것을 자유롭게 수행할 수 있습니다.Oracle 드라이버와 같은 일부 드라이버는 행을 청크로 가져오기 때문에 많은 메모리 없이도 매우 큰 결과 집합을 읽을 수 있습니다.다른 운전자들은 한 번에 모든 결과를 읽었고, 저는 그것이 당신의 운전자가 하고 있는 것이라고 생각합니다.
드라이버를 SQL Server 2008 버전(더 나은 버전) 또는 오픈 소스 jTDS 드라이버로 업그레이드할 수 있습니다.
연결의 자동 커밋이 꺼져 있는지 확인해야 합니다. 그렇지 않으면 setFetchSize가 적용되지 않습니다.
dbConnection.setAutoCommit(false);
편집: 이 수정 프로그램을 사용했을 때 Postgres에 특화되어 있었지만 SQL Server에서 계속 작동하기를 바랍니다.
문 인터페이스 문서
문서:
void setFetchSize(int rows)
더 많은 행이 필요할 때 데이터베이스에서 가져올 행 수에 대한 힌트를 JDBC 드라이버에 제공합니다.
이 ebook J2EE 및 Bey By Art Taylor를 읽어보십시오.
mssql jdbc가 전체 결과 집합을 버퍼링하는 것처럼 들립니다.selectMode=message 또는 responseBuffering=message라고 하는 연결 문자열 매개 변수를 추가할 수 있습니다.2005 mssql jdbc 드라이버 버전 2.0 이상인 경우 응답 버퍼링은 기본적으로 적응형으로 설정됩니다.
http://msdn.microsoft.com/en-us/library/bb879937.aspx
쿼리에서 반환되는 행을 제한하고 결과를 페이지로 이동하는 것으로 알고 있습니다.그렇다면 다음과 같은 작업을 수행할 수 있습니다.
select * from (select rownum myrow, a.* from TEST1 a )
where myrow between 5 and 10 ;
당신은 단지 당신의 경계를 결정해야 합니다.
사용해 보십시오.
String SQL = "select col1, col2, coln from mytable where timecol = yesterday";
connection.setAutoCommit(false);
PreparedStatement stmt = connection.prepareStatement(SQL, SQLServerResultSet.TYPE_SS_SERVER_CURSOR_FORWARD_ONLY, SQLServerResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(2000);
stmt.set....
stmt.execute();
ResultSet rset = stmt.getResultSet();
while (rset.next()) {
// ......
저도 프로젝트에서 똑같은 문제를 겪었습니다.문제는 가져오기 크기가 충분히 작더라도 JDBCTemplate가 쿼리의 모든 결과를 읽고 대용량 목록에 매핑하여 메모리가 손실될 수 있다는 것입니다.나는 객체 스트림을 반환하는 함수를 만들기 위해 NamedParameterJdbcTemplate를 확장했습니다.이 스트림은 일반적으로 JDBC에서 반환되는 ResultSet을 기반으로 하지만 스트림에서 필요한 경우에만 ResultSet에서 데이터를 가져옵니다.이 스트림이 뱉는 모든 개체에 대한 참조를 유지하지 않으면 작동합니다.org.springframework.jdbc.core 구현에 대해 많은 영감을 얻었습니다.JdbcTemplate#execute(또는 springframework.jdbc.core).연결 콜백).유일한 실질적인 차이는 ResultSet으로 수행할 작업과 관련이 있습니다.결과 집합을 마무리하기 위해 이 함수를 작성하게 되었습니다.
private <T> Stream<T> wrapIntoStream(ResultSet rs, RowMapper<T> mapper) {
CustomSpliterator<T> spliterator = new CustomSpliterator<T>(rs, mapper, Long.MAX_VALUE, NON-NULL | IMMUTABLE | ORDERED);
Stream<T> stream = StreamSupport.stream(spliterator, false);
return stream;
}
private static class CustomSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
// won't put code for constructor or properties here
// the idea is to pull for the ResultSet and set into the Stream
@Override
public boolean tryAdvance(Consumer<? super T> action) {
try {
// you can add some logic to close the stream/Resultset automatically
if(rs.next()) {
T mapped = mapper.mapRow(rs, rowNumber++);
action.accept(mapped);
return true;
} else {
return false;
}
} catch (SQLException) {
// do something with this Exception
}
}
}
논리를 추가하여 스트림을 "자동 닫기 가능"으로 만들 수 있습니다. 그렇지 않으면 스트림을 종료할 때 닫는 것을 잊지 마십시오.
언급URL : https://stackoverflow.com/questions/1318354/what-does-statement-setfetchsizensize-method-really-do-in-sql-server-jdbc-driv
'programing' 카테고리의 다른 글
pyspark 데이터 프레임에 고유한 열 값 표시 (0) | 2023.06.20 |
---|---|
PL/SQL에서 문자열을 비교하는 방법은 무엇입니까? (0) | 2023.06.20 |
WHERE 절과 함께 사용할 경우 Oracle CONNECT BY 최적화 (0) | 2023.06.20 |
Oracle에서 키워드를 제외하고 (0) | 2023.06.20 |
Git의 한 분기에서 다른 분기로 특정 커밋을 병합하려면 어떻게 해야 합니까? (0) | 2023.06.20 |