SQLP/오라클 성능 고도화 원리와 해법
데이터베이스 Call 최소화 원리
개발자 키우기
2024. 1. 11. 12:28
1. Call 통계
- SQL 트레이스 리포트에서 Call 통계 부분을 보면 Parse Call은 커서를 파싱 하는 과정에 대한 통계로서 실행계획을 생성하거나 찾는 과정에 관한 정보를 포함하고 있다. 바인드변수, 세션 커서 캐싱, 애플리케이션 커서 캐싱을 통해 Parse Call이 발생하지 않게 할 수 있다. Execute Call은 커서를 실행하는 단계에 대한 통계이며 주로 DML문을 수행할 때나 select문일 때 커서를 오픈하면서 카운트된다. Fetch Call은 select문에서 실제 레코드를 읽어 사용자가 요구한 결과집합을 반환하는 과정에 대한 통계이기 때문에 DML문은 Fetch Call이 발생하지 않는다.
2. User Call vs. Recursive Call
- User Call은 OCI(Oracle Call Interface)를 통해 오라클 외부로부터 들어오는 Call을 말하며 WAS에서 발생한다. User Call을 최소화하기 위해서 One-SQL 구현, Array Processing, 부분범위처리, 효율적인 화면 페이지 처리, 사용자 정의 함수나 프로시저, 트리거의 적절한 활용 등이 있다.
- Recursive Call은 오라클 내부에서 발생하는 Call을 말하며 SQL 파싱과 최적화 과정에서 발생하는 Data Dictionary 조회, PL/SQL로 작성된 사용자 정의 함수, 프로시저, 트리거 내에서의 SQL 수행할 때 Recursive Call이 수행된다. Recursive Call을 최소화하기 위해서는 하드파싱 발생 횟수를 줄이고 PL/SQL로 작성한 프로그램을 무분별하게 사용하지 않아야 한다.
3. 데이터베이스 Call이 성능에 미치는 영향
- User Call이 많은 경우 데이터베이스에서 처리한 시간보다 데이터베이스에서 WAS로 데이터를 전달하는 네트워크 구간에서 소비한 시간이 더 길어진다. 따라서 One-SQL로 로직을 통합하여 성능을 개선해야 한다.
4. Array Processing 활용
- Array Processing 기능을 활용하면 한 번의 SQL 수행으로 다량의 로우를 동시에 DML 할 수 있다. 자바에서 FetchSize를 늘려서 배치를 수행한다.
5. Fetch Call 최소화
- 쿼리 결과집합을 전송할 때, 사용자로부터 Fetch Call이 있을 때마다 일정량씩 나누어 전송하는 것을 부분범위처리 라고 한다. 보통 페이징 처리할 때 사용되며 네트워크를 통해 전송해야 할 데이터양에 따라 ArraySize를 적절하게 조절하는 것도 좋다.
- OLTP성 업무에서 인덱스와 부분범위처리를 사용하면 대규모 테이블이라도 빠르게 처리가 가능하다. 하지만 OLAP나 DW성 쿼리처럼 결과집합 전체를 Fetch 해야 한다면 부분범위처리는 의미가 없다.
6. 페이지 처리의 중요성
- 페이지 단위로 화면에서 필요한 만큼씩 Fetch Call을 하고 그 데이터 양만큼 ArraySize를 조절하여 네트워크를 통해 전송하고 인덱스와 부분범위처리 원리를 이용해서 각 페이지에 필요한 최소량만 I/O 해야 한다.
7. PL/SQL 함수의 특징과 성능 부하
- PL/SQL도 인터프리터 언어이기 때문에 Native 코드로 완전히 컴파일된 내장 함수에 비해 많이 느리다. 연산 위주의 작업을 주로 수행한다면 좋을 수도 있다. 하지만 작성한 함수 실행 시 매번 SQL 실행엔진과 PL/SQL 가상 머신 사이에 콘텍스트 스위칭이 일어나며 심각한 성능 부하를 일으킬 수 있다. 특히 Recursive Call을 포함하는 함수를 사용하면 더욱더 성능 부하를 일으킨다. 또한 함수/프로시저를 잘못 사용하면 성능은 물론 데이터 정합성까지 해칠 수 있으므로 사용할 때는 항상 주의해야 한다.
8. PL/SQL 함수 호출 부하 해소 방안
- 단순 결과를 변환하는 함수를 사용하는 거라면 로직을 풀어서 decode, case문으로 전환하거나 조인문으로 구현할 수 있으면 전환해야한다. 만약 뷰 머지가 발생하여 함수가 추가적으로 수행된다면 no_merge 힌트를 사용하자.
- 스칼라 서브쿼리의 캐싱효과를 이용하여 함수 호출을 최소화 시킬 수 있다.
- 함수가 쿼리문을 포함하지 않을 때는 Deterministic 을 선언하여 캐싱효과를 얻을 수 있다.
- 참고 서적 : 오라클 성능 고도화 원리와 해법 1 -