2012-04-16 3 views
6

JDBC를 사용하여 데이터베이스 독립적 인 응용 프로그램을 작성하려고합니다. 이제 일부 테이블에서 상위 N 개의 항목을 가져 오는 방법이 필요합니다. JDBC에 setMaxRows 메서드가 있다는 것을 알았지 만 데이터베이스를 사용하면 모든 결과가 누출되어 무서워서 JDBC 드라이버 만 결과를 줄일 수 있으므로 사용하기가 쉽지 않습니다. 10 억 개의 행이있는 테이블에서 상위 5 개 결과가 필요하면 내 목이 부러 질 것입니다 (테이블의 인덱스는입니다).JDBC setMaxRows 데이터베이스 사용량

모든 종류의 데이터베이스에 대한 특수한 SQL 문을 작성하는 것은 좋지 않지만 데이터베이스가 영리한 쿼리 계획을 세우고 필요한 것보다 더 많은 결과를 가져 오는 것을 중지하게합니다.

setMaxRows을 사용하면 데이터베이스가 제대로 작동하지 않는다고 말할 수 있습니까?

최악의 경우에 나는 희망하는 방식으로이 작업에 의존 할 수 없다고 생각합니다. 저는 주로 Postgres 9.1과 Oracle 11.2에 관심이 있습니다. 따라서 누군가이 데이터베이스에 대한 경험이 있다면 앞으로 나아 갑니 다.

+2

좋은 질문입니다. javadoc에서는 "이 Statement 객체에 의해 생성 된 ResultSet 객체가 주어진 수에 포함될 수있는 최대 행 수에 대한 제한을 설정합니다. 제한을 초과하면 초과 행이 자동으로 삭제됩니다." 내가 읽은 방식은 JDBC 드라이버가 작업을 수행 할 수 있음을 의미합니다. JDBC 구현에 의존하는 것으로 의심됩니다. –

답변

3

데이터베이스가 영리 쿼리 계획을하고 필요 이상으로 결과를 가져 오는 멈추게됩니다.

당신이 사용하는 경우

PostgreSQL :

SELECT * FROM tbl ORDER BY col1 LIMIT 10; -- slow without index 

또는 :

SELECT * FROM tbl LIMIT 10;    -- fast even without index 

Oracle :

SELECT * 
FROM (SELECT * FROM tbl ORDER BY col1 DESC) 
WHERE ROWNUM < 10; 

.. 그러면 단지 행 수가 이되고이 반환됩니다. 그러나 상위 10 개를 선택하기 전에 행을 정렬하는 경우 모두 기본적으로 행을 규정하는 행은 으로 표시되고 정렬하기 전에으로 읽습니다.

색인 매칭은 이러한 오버 헤드를 예방할 수 있습니다!


당신이 JDBC 실제로 데이터베이스 서버로 보낼 것을, 확실하지 않은 경우, 테스트를 실행하고 데이터베이스 엔진이받은 문장을 기록합니다. PostgreSQL의에서는 set in postgresql.conf 할 수 있습니다

log_statement = all 

(그리고 다시로드) 서버로 전송 모든 문을 로그인합니다. 테스트 후 또는 로그 파일이 커질 수 있으므로 해당 설정을 다시 설정하십시오.

1

수십억 개의 행으로 당신을 죽일 수도/죽일 수도있는 것은 쿼리의 (가능성이 높은) ORDER BY 절입니다. 인덱스를 사용하여이 순서를 설정할 수없는 경우 . . 그것은 목을 부러 뜨릴거야 :)

나는 여기에 jdbc 드라이버에 의존하지 않을 것이다. 이전의 의견은 그것이 실제로 무엇을하는지 (다른 rdbms를 보면서) 불분명 함을 시사한다.

쿼리의 속도가 걱정된다면 LIMIT 절을 사용할 수도 있습니다.LIMIT을 사용한다면 적어도 DB 서버로 전달 될 수 있습니다.

편집 : 죄송합니다. 오라클이 LIMIT을 지원하지 않는다는 사실을 알지 못했습니다.

1

PostgreSQL 9.1에 관한 질문에 대한 직접적인 답변 : 예, JDBC 드라이버는 설정 한 것 이상의 행 생성을 서버에 알립니다.

인덱스와 계획에 따라 서버에서 매우 많은 수의 행을 검색하여 원하는 5 개를 찾을 수 있습니다. 적절한 서버 구성은이를 방지하기 위해 비용을 정확하게 모델링하는 데 도움이 될 수 있지만, 값 분포가 비정상적인 경우 CTE와 같은 최적의 장벽을 도입하여 계획을 강요하여 좋은 계획을 세울 필요가 있습니다.

관련 문제