함수 튜닝

함수 튜닝

개발자를 위한 오라클 SQL 튜닝 내용에서 참고한 내용입니다.

Intro

분석 함수 튜닝

집계 함수의 한계

  • 집계 함수(Aggregate Function)

    • SUM(), AVG(), COUNT()

    • SQL문에서 나온 결과 행들이 여러 개라면, 집계 함수를 사용함으로써 결과 행의 건수가 N보다 적어지는 한계가 있다.

    • 집계 함수는 결과 행의 건수를 보장하지 않는다.

    • 집계 내역을 뽑으면서 다른 정보도 같이 보려는 경우, 집계 함수는 적합하지 않다.

분석 함수의 유용성

  • 분석 함수(Analytic Function)

    • WHERE 절을 통해 나온 행들을 대상으로 다양한 집계나 통계를 구할 때 사용하는 함수이다.

분석 함수 튜닝

  • 분석 함수 튜닝이란 분석 함수를 이용하여 SQL문의 성능을 극대화하는 모든 활동을 의미한다.

주요 분석 함수

  • RANK

    • SELECT 문의 결과 내에서 특정 조건에 따른 순서를 구하는데, 동일한 값은 동일한 순위가 매겨진다.

  • ROW_NUMBER

    • SELECT 문의 결과 내에서 특정 조건에 따른 순위를 구하는데, 동일한 값이라도 다른 순위를 매겨준다.

    • 시퀀스를 구하는 용도로 자주 사용한다.

  • SUM

    • SELECT 문 결과 내에서 특정 값의 합계를 계산하는 함수이다.

  • SAL 컬럼 기준으로 정렬한 상태에서 각각의 행은 첫 행에서 현재 행까지의 합계를 산출하게 된다.

  • MAX

    • SELECT 문 결과 내에서 특정 조건에 따른 최대값을 구하는 함수이다.

  • AVG

    • SELECT 문 결과 내에서 특정 조건에 따른 평균값을 구하는 함수이다.

RANK 함수를 이용하여 반복적인 테이블 스캔 제거

  • 테이블 생성

  • 데이터 입력

  • 주문 테이블 NOLOGGING 모드 설정

  • 주문 테이블에 1000만건 데이터 입력

  • 기본키 생성

  • 통계정보 생성

분석 함수 튜닝 전 상황

  • SQL 분석

    • NO_MERGE 힌트를 사용함으로써 인라인 뷰가 View Merging되어 메인쿼리인 TB_ORD Y와 같은 레벨에서 수행되는 것을 방지해준다.

    • 즉, 인라인 뷰 X 내의 SQL은 해당 인라인 뷰 내에서 처리하게 한다.

  • SQL의 문제점

    • TB_ORD 테이블에는 별도의 인덱스가 존재하지 않지만, SQL은 TB_ORD 테이블을 2번 스캔하고 있다.

    • 이런 SQL은 분석 함수를 이용하여 한 번만 스캔하도록 튜닝해야 한다.

  • 실행 계획

    • 인라인 뷰 내에 TB_ORD 테이블을 테이블 풀 스캔(TABLE ACCESS FULL)한다.

    • GROUP BY 연산을 수행한다.

    • GROUP BY 연산에 대한 인라인 뷰

    • TB_ORD 테이블을 테이블 풀 스캔(TABLE ACCESS FULL)한다.

    • GROUP BY 연산의 결과 값과 인라인 뷰 결과를 해시 조인(Hash Join)한다.

    • 소팅 연산(Sort Order By)을 수행

    • SELECT 절의 연산을 수행

분석 함수 튜닝 후 상황

  • SQL 분석

    • RANK 함수를 사용하여 ORD_DT 별 ORD_AMT의 내림차순 순위를 구한다.

    • RANK 함수로 구한 순위 중 1위인 건만 추출한다.

  • 실행 계획

    • 인라인 뷰 내에 TB_ORD 테이블을 테이블 풀 스캔(TABLE ACCESS FULL) 한다.

    • RANK 함수 연산을 수행한다.

    • 테이블 풀 스캔 연산의 결과에 대한 인라인 뷰이다.

    • SELECT 절의 연산을 수행한다.

SUM 함수를 이용하여 반복적인 테이블 스캔 제거하기

  • 테이블 생성

  • 데이터 입력

  • 기본키 생성

  • 통계정보 생성

튜닝 전 상황

  • SQL 분석

    • 월별 누적 합을 구하기 위해서는 BA보다 작아야 한다.

    • AGENT_NO 컬럼을 기준으로 조인 조건을 걸어준다. 이러면 AGENT_NO별 합계를 구할 수 있다.

  • SQL 문제점

    • TB_SALE_MONTH 테이블을 2번 스캔하고 있다.

    • SUM 분석 함수를 사용한다면 해당 테이블을 단 한번만 스캔하여 결과를 도출할 수 있다.

  • 실행 계획

    • TB_SALE_MONTH 테이블을 테이블 풀 스캔(TABLE ACCESS FULL)한다.

    • TB_SALE_MONTH 테이블을 테이블 풀 스캔(TABLE ACCESS FULL)한다.

    • 위의 테이블 풀 스캔한 두 결과를 해시 조인(HASH JOIN)한다.

    • GROUP BY 연산을 한다.

    • SELECT 절의 연산을 수행한다.

튜닝 후 상황

  • SQL 분석

    • 분석 함수인 SUM를 이용

    • AGENT_NO 컬럼을 기준으로 잡는다.

    • AGENT_NO과 YYYYMM 컬럼을 기준으로 정렬을 수행한다.

    • 합계 연산의 범위를 지정한다.

    • 맨 처음부터 현재 행까지의 합계를 낸다.

  • 실행 계획

    • TB_SALE_MONTH 테이블을 테이블 풀 스캔(TABLE ACCESS FULL)한다.

    • SUM 분석 함수를 수행한다.

    • SELECT 절의 연산을 수행한다.

사용자 정의 함수 튜닝

사용자 정의 함수

  • 사용자 정의 함수(User Defined Function)는 특정 업무 프로세스를 사용자가 정의해두고 필요할 때 호출하여 사용하는 함수를 의미한다.

예시

  • 특정 사원번호의 급여를 10% 인상한 후 인상된 급여를 리턴하는 사용자 정의 함수이다.

사용자 정의 함수의 재귀 호출 부하

  • 내장 함수(Built-In Function)와 사용자 정의 함수(User Defined Function)가 있다.

  • 내장 함수는 DBMS 엔진 내에 네이티브 코드로 컴파일된 상태로 존재하므로 빠른 속도를 보장한다.

  • 사용자 정의 함수는 PL/SQL 가상 머신 내에서 구동되어 내장 함수보다 컨텍스트 스위칭(Context-Switching) 부하가 발생한다.

  • 이러한 부하를 재귀 호출(Recursive Call) 부하라 한다.

사용자 정의 함수 튜닝

  • 사용자 정의 함수를 사용해야 하는 경우 성능을 고려하여 SQL 튜닝을 진행해야 한다.

사용자 정의 함수 재귀 호출 부하 최소화하기

  • 테이블 생성

  • 데이터 입력

  • 기본키 생성

  • 인덱스 구성

  • 통계 정보 생성

  • 사용자 정의 함수 생성

사용자 정의 함수 재귀 호출 부하 최소화하기 튜닝 전

  • SQL 분석

    • FN_GET_EMP_CNT 함수로 부서별 사원수를 구한다.

  • SQL 문제점

    • TB_EMP 테이블에는 10만건의 데이터가 존재하므로 FN_GET_EMP_CNT 함수는 총 10만번 호출된다.

    • 이러한 경우 재귀 호출 부하가 발생하게 되어 DBMS를 장애 상황으로 몰고 갈 수 있다.

  • 실행 계획

    • TB_EMP 테이블을 테이블 풀 스캔(TABLE ACCESS FULL)한다.

    • 소팅 연산(SORT ORDER BY)을 수행한다.

    • SELECT 절의 연산을 수행

사용자 정의 함수 재귀 호출 부하 최소화하기 튜닝 후

  • SQL 분석

    • 사용자 정의 함수 호출 부분을 DUAL 테이블을 이용하여 스칼라 서브쿼리로 구성

    • 스칼라 서브쿼리의 캐싱 효과로 인해 극적인 성능 향상을 이루게 된다.

스칼라 서브쿼리의 캐싱 효과 확인

  • 서브쿼리의 캐싱 효과를 확인하기 위한 DEPT_NO의 유일 값 확인

  • 10만 번 재귀 호출할 거를 49번으로 줄어들게 된다.

  • 유일 값이 적은 컬럼이 사용자 정의 함수에 입력 값으로 들어가면 재귀 호출을 획기적으로 줄일 수 있다.

  • 실행 계획

    • TB_EMP 테이블을 테이블 풀 스캔(TABLE ACCESS FULL)한다.

    • 소팅 연산(SORT ORDER BY)을 수행한다.

    • DUAL 테이블을 이용

    • SELECT 절의 연산을 수행한다.

Last updated

Was this helpful?