2009-10-01 3 views
8
나는 큰 결과를 반환하는 PostgreSQL의 쿼리를 실행하기 위해 노력하고있어

에서 제공 :JDBC + 대형 PostgreSQL의 쿼리는 메모리

connection.setAutoCommit(false); 
st = connection.createStatement(
    ResultSet.CONCUR_READ_ONLY, 
    ResultSet.TYPE_FORWARD_ONLY 
); 
st.setFetchSize(100); 
logMemory(); 
System.out.println("start query "); 
rs = st.executeQuery(queryString); 
System.out.println("done query "); 
logMemory(); 

을하지만,이 메모리를 많이 사용

Free memory; 4094347680 (= 3905 mb). 
start query 
done query 
Free memory; 2051038576 (= 1956 mb). 

을 (Runtime.getRuntime(). freeMemory())와 함께 인쇄됩니다.

지금까지는 작동하지만 데이터베이스는 훨씬 커질 것입니다. 나는 전체 결과를 기억할 필요가 없다. 각 행을 처리하고 결과를 디스크에 쓰고 다음 행으로 이동하면됩니다.

'setFetchSize'는 힌트 일 뿐이며, postgresql/jdbc가 무시할 경우 이상하게 느껴질 것입니다.

이 문제를 해결할 수있는 방법은 없나요? 내 유일한 생각은 지금까지 쿼리 결과를 디스크로 스트리밍하고 Java에서 파일을 구문 분석하는 배치 스크립트를 작성하는 것입니다 ...

+0

궁금한 점은 실행중인 최대 힙 크기는 얼마입니까? 아니면 기본값을 사용하고 있습니까? –

+1

-Xmx4096M -Xms4096M, Vista 8GB 시스템입니다. – kresjer

답변

7

아쉽게도 이것은 내가 본 JDBC를 사용하는 가장 불쾌한 버그 중 하나입니다. (당신이 커서 다른 기준을 충족 한대로) 당신은 어쩌면 단순히

st = connection.createStatement(); 

뿐만 아니라 작동합니다

st = connection.createStatement(
    ResultSet.TYPE_FORWARD_ONLY, 
    ResultSet.CONCUR_READ_ONLY 
); 

st = connection.createStatement(
    ResultSet.CONCUR_READ_ONLY, 
    ResultSet.TYPE_FORWARD_ONLY 
); 

을 변경해야합니다.

+0

버그가 무엇입니까? 실제 메모리 누수입니까? 아니면 계속 진행중인 것입니까? 포스트 그레스라고 생각하십니까? – rogerdpack

+0

@rogerdpack OP가'createStatement'의 메소드 매개 변수를 변경했습니다. 두 매개 변수는 모두 'int'이지만 몇 가지 다른 것을 의미합니다. 따라서 JDBC 구현의 버그는 아닙니다. –

9

Here은 결과 세트가 실제로 커서로 검색되도록하는 지침입니다 . 코드에서 알려진 모든 것을 치는 것처럼 보일 지 모르지만 명령문을 지정하지 않았으므로 세미콜론과 함께 여러 개 연결될 수 있습니다 (드물 긴하지만 코드 모양으로). V3 프로토콜 (버전 7.4 이상)을 사용해야합니다. 이 모든 것들이 당신의 사건에 적용됩니까?

+0

예, 모든 가이드 라인을 켜고/껐습니다. 성명은 간단합니다 hh.data, hh.customer_ID 선택 from dataTable hh hh.customer_ID = PH.customer_ID에 고객 가입 PH; 그리고 postgresql 8.3이고 postgresql-8.3-603.jdbc4.jar를 사용하고 있습니다. – kresjer

+0

나는 뒤죽박죽이다. 다음 단계는 PostgreSQL에 중점을 둔 그룹에 게시하는 것입니다. 연결에서 커서를 사용하도록 만들거나 강제로 할 수있는 다른 명확하지 않은 것들이있을 수 있습니다. 오픈 소스에 대한 좋은 점은 JDBC 소스 코드를 열어서 시나리오에서 어떤 일이 벌어지고 있는지 살펴볼 수있다. – Yishai

+1

답변에 감사드립니다. 당신이 인용 한 페이지에서'conn.setAutoCommit (false)'에 대한 요구 사항을 발견 할 때까지 나는이 문제를 하루 종일 고민하고있었습니다. – jutky

관련 문제