아무리 바빠도 공부는 해야지/Oracle

[Oracle] 효율적인 SQL 쿼리 최적화: 성능 개선을 위한 실전 노하우

지구라운드 2025. 1. 16. 10:01

Oracle SQL 쿼리 최적화

Oracle SQL 쿼리 최적화는 단순한 성능 향상뿐만 아니라 시스템 자원을 절약하고, 전체 데이터베이스 성능을 개선하는 데 중요한 역할을 합니다. 인덱스 활용, 조인 최적화, 서브쿼리 개선, 집합 연산 최적화 등 다양한 기법을 사용하여 쿼리 성능을 최적화할 수 있습니다. 쿼리 성능이 중요한 상황에서는 실행 계획 분석을 통해 성능 병목을 파악하고 개선하는 것이 필요합니다.

 

1. 쿼리 성능을 결정하는 주요 요소

쿼리 성능은 다양한 요소에 따라 달라집니다. 성능을 최적화하려면 먼저 성능에 영향을 미치는 주요 요소를 이해하는 것이 중요합니다.

  • 데이터 양: 처리해야 할 데이터의 양이 많을수록 성능에 영향을 미칩니다.
  • 인덱스 활용 여부: 적절한 인덱스를 사용하면 데이터 검색 속도를 획기적으로 개선할 수 있습니다.
  • 조인 방식: 잘못된 조인 방식은 쿼리 성능을 크게 저하시킬 수 있습니다.
  • 서브쿼리와 집합 연산: 서브쿼리나 집합 연산을 잘못 사용하면 쿼리가 비효율적으로 실행될 수 있습니다.

이러한 요소들을 잘 이해하고 최적화 기법을 적용하면 성능을 크게 향상시킬 수 있습니다.

 

2. 인덱스 활용 최적화
(1) 적절한 인덱스 사용

인덱스는 SQL 쿼리 성능 최적화에서 매우 중요한 역할을 합니다. 데이터베이스에서 특정 컬럼에 인덱스를 사용하면 검색 속도가 크게 향상됩니다. 그러나 모든 컬럼에 인덱스를 사용하는 것은 오히려 성능 저하를 초래할 수 있습니다. 인덱스를 만들 때는 조회가 자주 이루어지는 컬럼에만 인덱스를 추가하는 것이 좋습니다.

CREATE INDEX idx_emp_salary ON employees(salary);

이 예제에서는 employees 테이블의 salary 컬럼에 인덱스를 추가하여 급여를 기준으로 검색할 때 성능을 향상시킵니다.

 

(2) 다중 인덱스 사용 시 주의점

때로는 여러 개의 인덱스를 사용하는 것이 성능을 향상시킬 수 있지만, 다중 인덱스를 사용하는 경우에는 인덱스 병합이나 인덱스 선택성을 고려해야 합니다. 불필요한 인덱스는 삭제하여 성능을 최적화해야 합니다.

 

3. 조인 최적화
(1) 조인 순서 최적화

여러 테이블을 조인할 때, Oracle은 기본적으로 쿼리의 실행 계획을 선택하지만, 수동으로 조인 순서를 최적화하여 성능을 높일 수 있습니다. 예를 들어, 필터링 조건이 더 좁은 테이블을 먼저 조인하는 것이 효율적입니다.

SELECT * 
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE c.customer_type = 'VIP';
(2) 조인 타입 선택

Oracle에서는 다양한 종류의 조인(내부 조인, 외부 조인 등)을 지원합니다. INNER JOIN을 사용하면 일반적으로 성능이 더 좋습니다. OUTER JOIN은 모든 데이터에 대해 연산을 수행해야 하므로 성능이 저하될 수 있습니다.

 

4. 서브쿼리 최적화
(1) 서브쿼리 대신 조인 사용

서브쿼리는 읽기 편리할 수 있지만, 성능 면에서는 비효율적일 수 있습니다. 서브쿼리 대신 조인을 사용하면 성능을 크게 향상시킬 수 있습니다. 특히, IN이나 EXISTS와 같은 서브쿼리는 조인으로 대체하는 것이 좋습니다.

-- 서브쿼리
SELECT * 
FROM employees 
WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'New York');

-- 조인으로 변경
SELECT e.* 
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE d.location = 'New York';

위 예제에서 서브쿼리를 조인으로 변경하여 성능을 개선할 수 있습니다.

(2) 서브쿼리에서 EXISTS와 IN의 차이

IN은 전체 서브쿼리 결과를 가져와 비교하므로 데이터가 많을 경우 성능 저하를 일으킬 수 있습니다. 반면, EXISTS는 조건에 맞는 첫 번째 행만 찾으면 결과를 반환하므로 더 효율적입니다. 따라서 서브쿼리에서는 EXISTS를 사용하는 것이 성능 면에서 더 유리할 수 있습니다.

 

5. 집합 연산 최적화
(1) UNION과 UNION ALL 비교

**UNION**은 중복을 제거한 결과를 반환하므로 추가적인 정렬 작업이 필요하고, 이는 성능을 저하시킬 수 있습니다. 반면, **UNION ALL**은 중복을 제거하지 않기 때문에 성능이 더 뛰어나며, 중복을 허용하는 경우에는 **UNION ALL**을 사용하는 것이 좋습니다.

-- `UNION` 사용
SELECT employee_id FROM employees WHERE department_id = 10
UNION
SELECT employee_id FROM employees WHERE department_id = 20;

-- `UNION ALL` 사용
SELECT employee_id FROM employees WHERE department_id = 10
UNION ALL
SELECT employee_id FROM employees WHERE department_id = 20;
 

 

6. 실행 계획 분석 (EXPLAIN PLAN)
(1) 실행 계획을 통한 성능 분석

SQL 쿼리를 최적화하려면 실행 계획을 분석하는 것이 필수적입니다. EXPLAIN PLAN을 사용하면 쿼리가 실제로 어떻게 실행되는지, 어떤 인덱스나 조인 방식이 사용되는지 파악할 수 있습니다. 이를 통해 성능 병목 현상을 찾아낼 수 있습니다.

EXPLAIN PLAN FOR 
SELECT * 
FROM employees 
WHERE department_id = 10;

실행 계획을 통해 쿼리가 어떤 인덱스를 사용하고, 어떤 방식으로 테이블을 스캔하는지 확인할 수 있습니다.

 

7. 캐싱과 데이터 파티셔닝 활용
(1) 캐싱 사용

쿼리 캐싱은 자주 실행되는 쿼리의 결과를 캐시하여 성능을 향상시킬 수 있습니다. Oracle에서는 결과 캐시를 활용하여 쿼리의 결과를 메모리에 저장하고, 동일한 쿼리가 실행될 때 캐시된 결과를 반환합니다.

(2) 데이터 파티셔닝

파티셔닝은 대용량 테이블을 여러 개의 작은 파티션으로 나누어 관리하는 방법입니다. 이를 통해 쿼리 성능을 향상시키고, 데이터의 관리도 용이해집니다. 파티셔닝을 적절히 사용하면 데이터 검색 속도가 개선되고, 전체 쿼리 성능을 최적화할 수 있습니다.

 

반응형