2012-08-06 2 views
0

최근에 문제가 생겼습니다. 오라클 DB에서 일괄 처리 된 데이터 테이블 (예 : 일괄 처리가 4-5000)을 가져 오려고했습니다. 내 이전 "일반"솔루션은 다음과 같은 일이 어떤 종류로 선택을 포장했다 : Oracle에서 느린 내부 -N 선택

SELECT * FROM (
    SELECT ROWNUM AS RN, INNERSELECT.* FROM (
     select THINGS1, THINGS2 from MYTABLE) 
    ) 
INNERSELECT WHERE ROWNUM < 4001) WHERE RN >= 3001 
는 ROWNUM 테두리가 높을 때 느린 것 같았다 (예를 4-500.000에 대한) 다음 선택은 이상 걸릴 것입니다 10-20 초. 그리고 값을 늘리면 시간이 선형 적으로 증가합니다. 물론 이유를 알기 때문에 데이터를 일괄 적으로 얻을 수있는 또 다른 솔루션을 찾고 싶지만 보장 된 시간 프레임을 원했습니다. 조금 느린
SELECT * FROM (
    SELECT INNERSELECT.*, ROW_NUMBER() OVER (ORDER BY INNERSELECT.ROWID) RN FROM 
    (select THINGS1, THINGS2 from MYTABLE) 
    INNERSELECT 
) WHERE RN BETWEEN 3001 AND 4000; 

은 (그것은 테스트를위한 데이터의 배치를 얻을 3-4 초가 소요),하지만 난 눈에 띄는 성능 저하없이 배치 크기를 증가시킬 수있다 : 그럼 난 선택의이 종류를 사용 높은 값에 대해서도 동일합니다. 현재 문제는입니다. DB에서 여러 스레드의 여러 테이블을 선택하면 성능이 떨어집니다. 스레드를 3 개만 사용하면 성능이 떨어집니다 (현재 프로젝트에 사용되는 16 개는 아닙니다). JDBC 연결은 풀링되고 성능 저하는 서버 측에서 발생합니다. select가 CPU 시간을 먹고있어 아무것도 할 수 없다는 것이 확실하다고 생각하지만,이 모든 것을 최적화하는 방법에 대한 힌트 나 팁이 있기를 바랍니다.

다른 문제는, 예를 들어 복사 테이블을 사용할 수 있도록 우리가 특정 프로젝트되지 사용하는 도구, 그것은 등 가능한 한 일반적으로 사전에 답변을

감사를 가지고 있다는 것입니다

답변

1

MYTABLE가 가지고있는 가정의 숫자 기본 키 ID, 하나의 전술은 16 개 스레드의 각이 쿼리 실행해야하는 것입니다 :

SELECT THINGS1, THINGS2 
FROM MYTABLE 
WHERE MOD(ID,15) = :THREAD_NUMBER 

각 스레드 15 0에서 :THREAD_NUMBER에 대해 고유 한 값을 얻을 것입니다. 즉, 각 스레드는 (대략) 행의 1/16을 차지합니다.

+0

이것은 번호가 지정된 각 스레드에서 전체 테이블 스캔이 발생할 것으로 생각합니다. 이것을 피하는 가장 좋은 방법은 MYTABLE에서 일부 파티셔닝을 사용하는 것입니다. – OraNob

+0

이상적으로, 예, 데이터가 분할되거나 쿼리되는 열의 인덱스가 있고 인덱스를 전체 스캔 할 수 있습니다. –

+0

글쎄 이것은 좋은 개선이다. 감사. – newhouse

0
SELECT * FROM (
    SELECT INNERSELECT.*, ROW_NUMBER() OVER (ORDER BY INNERSELECT.ROWID) RN FROM 
    (select THINGS1, THINGS2 from MYTABLE) 
    INNERSELECT 
) WHERE RN BETWEEN 3001 AND 4000; 

(MYTABLE에서 THINGS1, THINGS2 선택)

이 얼마나 많은 행을 검색합니까? 당신이 이것에 일종의 제한 조항을두면 시스템이 FULL TABLE SCAN이나 INDEX SCAN을하지 않아도된다.

INNERSELECT.ROWID

BY

ORDER 그것은 이런 종류를 발행 할 필요가 있습니까? 특히 정렬 기준이 시스템 생성 값이기 때문에. 큰 정렬은 데이터베이스에 큰 영향을 줄 수 있습니다.

기억해야 할 중요한 점은 오라클에서 ROWNUM을 사용하여 레코드를 추출하는 것입니다. 데이터베이스는 마지막 하나 인 ~ 중 하나 인 ORDER BY 이전 레코드로 ROWNUM을 적용합니다.