저는 매일 수백만 개의 레코드가 포함된 매우 큰 테이블을 갖고 있으며, 하루가 끝날 때마다 전날의 모든 레코드를 가져옵니다. 제가 하는 방법은 다음과 같습니다.
String SQL = "timecol = 어제인 mytable에서 col1, col2, coln을 선택합니다."; Statement.executeQuery(SQL);
문제는 이 프로그램이 모든 결과를 메모리에 저장하고 처리하기 때문에 약 2GB 정도의 메모리가 필요하다는 점입니다.
Statement.setFetchSize(10)
설정을 시도했지만 OS에서 정확히 동일한 메모리를 가져오지만 차이는 없습니다. 저는 이를 위해 Microsoft SQL Server 2005 JDBC 드라이버를 사용합니다.
Oracle 데이터베이스 드라이버처럼 결과를 작은 덩어리로 읽어서 쿼리가 실행될 때 몇 개의 행만 표시하고 아래로 스크롤하면 더 많은 결과를 표시하는 방법이 있습니까?
JDBC에서
setFetchSize(int)
메소드는 JVM에서 데이터베이스로의 네트워크 호출 수와 해당 데이터 양을 제어하므로 JVM 내 성능 및 메모리 관리에 매우 중요합니다. 결과 집합 처리에 사용되는 RAM입니다.기본적으로 setFetchSize(10)이 호출되고 드라이버가 이를 무시하는 경우 가능한 옵션은 두 가지뿐입니다.
RESULT-SET은 쿼리에 대한 응답으로 데이터베이스에 마샬링된 행 수입니다. ROW-SET은 JVM에서 DB로 호출할 때마다 RESULT-SET에서 추출된 행 블록입니다. 이러한 호출 수와 처리에 필요한 RAM은 가져오기 크기 설정에 따라 다릅니다.
따라서 RESULT-SET의 행이 100개이고 가져오기 크기가 10인 경우 언제든지 약 10*{row-content-size} RAM을 사용하여 모든 데이터를 검색하는 10개의 네트워크 호출이 있습니다.
기본 가져오기 크기는 10으로 매우 작습니다. 게시된 경우 드라이버는 가져오기 크기 설정을 무시하고 한 번의 호출로 모든 데이터를 검색하는 것으로 보입니다(많은 RAM이 필요하며 최적으로 최소한의 네트워크 호출이 필요함).
ResultSet.next()
에서 발생하는 현상은 실제로 RESULT-SET에서 한 번에 한 행씩 가져오지 않는다는 것입니다. (로컬) ROW-SET에서 해당 데이터를 가져오고 로컬 클라이언트의 데이터가 소진되면 서버에서 다음 ROW-SET(보이지 않는)을 가져옵니다.설정은 단지 "힌트"일 뿐이므로 이 모든 것은 드라이버에 따라 다르지만 실제로는 이것이 작동하는 드라이버와 데이터베이스의 수에 따라 결정됩니다(여러 버전의 Oracle, DB2 및 MySQL에서 입증됨). p>