DBMS/개념

31_ 데이터베이스 성능 튜닝 정리

seungwon-1 2025. 11. 10. 20:16

성능 튜닝이라는 말이 거창하게 들리지만, 결국은 “시스템이 얼마나 빠르고 효율적으로 돌아가느냐”의 문제다.
한마디로 응답 속도 향상 + 리소스 낭비 최소화가 목표다.

 

1. 성능 튜닝의 기본 개념

데이터베이스 성능을 평가할 때 주로 보는 지표는 다음과 같다.

  • 응답 시간 (Response Time): 쿼리 실행 후 결과가 나오는 데 걸리는 시간
  • 처리량 (Throughput): 단위 시간당 처리 가능한 작업 수
  • CPU 사용률, 메모리 사용량, I/O 작업량

이 지표들은 서로 연관되어 있어서, 한쪽을 올리면 다른 한쪽이 떨어지기도 한다.
튜닝의 핵심은 균형 잡힌 최적화다.

 

2. 실행 계획 분석

쿼리가 실제로 어떻게 실행되는지를 확인하는 게 성능 튜닝의 첫걸음이다.

EXPLAIN PLAN FOR
SELECT * FROM employees;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

이 실행 계획을 보면 옵티마이저가 어떤 순서로 테이블을 읽고 조인을 수행하는지 확인할 수 있다.

주요 요소

  • 테이블 액세스 방식
    • Full Table Scan: 전체 테이블을 읽는 방식 (대량 데이터 시 유리)
    • Index Scan: 인덱스를 통해 필요한 데이터만 읽는 방식 (소량 조회 시 빠름)
  • 조인 방식
    • Nested Loop: 작은 테이블 기준으로 반복 탐색 (소규모 조인에 적합)
    • Hash Join: 대용량 데이터를 빠르게 매칭할 때 사용
    • Sort Merge Join: 두 테이블이 이미 정렬되어 있을 때 효율적
  • 실행 순서와 비용
    • 실행 순서는 들여쓰기 순서대로 해석
    • 비용이 낮을수록 효율적인 실행 경로

 

3. 인덱스 최적화

인덱스는 튜닝의 핵심이다.
하지만 잘못 만들면 오히려 성능이 떨어지기 때문에 선택도(Selectivity) 를 고려해야 한다.

  • 선택도 높을수록 좋음
    (예: 주민번호 > 성별)
  • WHERE 절 조건 순서
    • 자주 쓰이는 조건, 등호(=) 조건을 앞에 배치
    • 선택도가 높은 컬럼부터 인덱스 생성
  • 복합 인덱스
    여러 컬럼을 함께 검색할 때 유용
    (예: (부서번호, 입사일자))

인덱스는 시간이 지나면 단편화되기 때문에 주기적으로 재구성해줘야 한다.

CREATE INDEX emp_name_idx ON employees(last_name);
ALTER INDEX emp_name_idx REBUILD;

 

4. 쿼리 최적화 기법

쿼리를 효율적으로 작성하는 습관이 결국 최고의 튜닝이다.

WHERE 절 최적화

  • 조건 순서를 잘 정리 (선택도 높은 조건 먼저)
  • 함수 사용은 최소화 (인덱스 사용 방해)
  • 불필요한 DISTINCT 제거

조인 최적화

  • 작은 테이블부터 조인
  • 인덱스가 걸린 컬럼 기준으로 조인
  • 데이터 분포를 고려

예시 비교

-- 비효율적인 쿼리
SELECT * 
FROM employees e, departments d
WHERE e.department_id = d.department_id;

-- 최적화된 쿼리
SELECT e.employee_id, e.first_name, d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE e.salary > 5000;

명시적 JOIN 구문을 쓰는 게 가독성과 성능 모두에서 좋다.

 

5. 통계 정보 관리

옵티마이저가 최적의 실행 계획을 세우려면 최신 통계 정보가 필요하다.
데이터가 변하면 반드시 다시 수집해야 한다.

EXEC DBMS_STATS.GATHER_SCHEMA_STATS('HR');

 

6. 메모리 관리

DB 성능은 디스크보다 메모리 활용에 더 영향을 받는다.

  • SGA (System Global Area): 모든 사용자 공유 메모리 (SQL, 캐시 등)
  • PGA (Program Global Area): 각 세션별 전용 메모리 (정렬, 세션 정보)
  • Buffer Cache: 자주 쓰는 데이터 캐시
  • Shared Pool: SQL 문장과 실행 계획 저장

메모리를 얼마나 잘 분배하느냐가 쿼리 속도를 결정한다.

 

 

7. 모니터링과 진단

성능 문제를 발견하려면 꾸준한 모니터링이 필수다.

  • AWR 리포트: 성능 통계를 자동 수집 (CPU, I/O, 대기 이벤트 등)
  • V$ 뷰: 실시간 세션 및 SQL 실행 상태 확인
  • ADDM: 자동으로 병목 구간과 개선 방향 제시
SELECT sql_id, sql_text, elapsed_time
FROM v$sql
WHERE parsing_schema_name = 'HR'
ORDER BY elapsed_time DESC;

 

8. 실습 예제: APPEND 힌트

APPEND 힌트는 대용량 데이터를 빠르게 넣을 때 유용하다.

INSERT /*+ APPEND */ INTO big_table
SELECT * FROM employees
WHERE department_id = 50;
  • 일반 INSERT: 버퍼 캐시를 거쳐 기록 (안정적이지만 느림)
  • APPEND: 바로 디스크에 기록 (빠르지만 동시성 작업 제한)

대용량 배치 작업 시에는 APPEND가 훨씬 효율적이다.