부분범위 처리
- 전체 쿼리 결과집합을 쉼 없이 연속적으로 전송하지 않고 사용자로 부터 Fetch Call이 있을 때마다 일정량씩 나누어 전송하는 것을 '부분범위 처리'라 한다.
- 최초 rs.next() 호출 시 Fetch Call을 통해 DB 서버로 부터 전송받은 데이터 10건을 클라이언트 캐시에 저장
- 이후 rs.next() 호출할 때는 Fetch Call을 발생시키지 않고 캐시에 데이터를 읽는다.
- 캐시에 저장한 데이터를 모두 소진한 상태에서 rs.next() 호출 시 Fetch Call을 통해 10건을 전송 받는다
- 100건을 다 읽을 때까지 2~3번 과정을 반복함.
정렬 조건이 있을 때 부분범위 처리
- 정렬 조건 컬럼이 선두인 인덱스가 있으면, 부분범위 처리가 가능
- 왜? 인덱스는 항상 정렬된 상태를 유지하기 때문
Array Size 조정을 통한 Fetch Call 최소화
- Array Size를 조정하면 Fetch Call 횟수를 그만큼 줄일 수 있음
- 반면 앞쪽 일부 데이터만 가져오는 경우 작게 설정하는 것이 유리함.
쿼리 툴에서 부분범위 처리
- 모든 DBMS는 데이터를 조금씩 나눠서 전송함
- 즉 부분범위 처리 방식으로 결과집합을 전송함
- 이 특징을 이용해 중간에 멈췄다가 사용자의 추가 요청이 있을 때마다 데이터를가져오도록 구현하고 안하고는 클라이언트 프로그램을 개발하는 개발자 몫이다.
OLTP환경에서 부분범위 처리에 의한 성능개선 원리
- OLTP는 Online Transaction Processing
- 말 그대로 온라인 트랜잭션을 처리하는 시스템을 말함
- 온라인 트랜잭션은 일반적으로 소량의 데이터를 읽고 갱신함(항상 소량 데이터만 조회하는 것은 아님)
- OLTP는 특정한 정렬 순서로 상위 일부 데이터만 확인한다.
- 인덱스와 부분범위 처리 원리를 잘 활용하면 OLTP 환경에서 극적인 성능 개선 효과를 얻음
멈출 수 있어야 의미있는 부분범위 처리
- 문제는 앞쪽 일부만 출력하고 멈출 수 있는가 이다. => 부분범위의 처리의 핵심
배치 I/O
- 읽는 블록마다 건건이 I/O Call을 발생시키는 비효율을 줄이기 위해 고안한 기능
데이터 정렬 이슈
- 배치 I/O 기능이 작동하면 인덱스를 이용해서 출력하는 데이터 정렬 순서가 매번 다를 수 있다.
- 즉, 실제 배치 I/O가 작동할 때는 데이터 출력 순서가 인덱스 정렬 순서와 다를 수 있다.
- 배치 I/O를 통해 얻을 수 있는 성능이 많음에도 불구하고 시스템 레벨에서 이를 비활성화 하는 경우가 있음
- 그 이유는 필요한 ORDER BY를 생략한 SQL 패턴 떄문
- ORDER BY가 없으면 결과집합의 정렬 순서를 보장할 필요가 없으므로 옵티마이저가 배치 I/O를 선택할 수 있고, 출력된 결과집합의 정렬 순서가 매번 다룰 수 있다.
- 오라클 기능이 개선되어서 이 패턴을 쓸 이유가 없어진지 오래됬고 그대로 둬도 상관없음
- 인덱스 구성을 변경하지 않는 한 결과집합의 정렬 순서가 보장됐기 때문!
- 12c로 업그레이드할 때 이 기능을 비활성화하는 쪽으로 결졍함
- 이제 인덱스 정렬 순서를 믿고 ORDER VY를 생략하는 개발 패턴을 사용하지 않아야 한다.!!