티스토리 뷰
데이터베이스는 애플리케이션의 성능을 좌우하는 핵심 요소입니다. 하지만 데이터량이 많아지거나 복잡한 쿼리를 실행하면 성능 저하를 경험할 수 있습니다. 이런 문제를 해결하려면 인덱스 최적화와 쿼리 최적화가 필수입니다. 이번 글에서는 실제 사례를 통해 데이터베이스 성능을 개선하는 방법을 알아보겠습니다.
1. 데이터베이스 성능 저하의 주요 원인
1.1 인덱스 부족
• 인덱스가 없으면 데이터베이스는 데이터를 검색할 때 전체 테이블을 스캔(Full Table Scan)해야 합니다. 이는 데이터량이 많을수록 시간이 오래 걸립니다.
1.2 비효율적인 쿼리
• 잘못된 쿼리 작성으로 인해 불필요한 데이터가 처리되거나, JOIN 조건이 비효율적으로 설정될 수 있습니다.
1.3 데이터베이스 설계 문제
• 비정규화된 테이블 구조, 데이터 중복 등은 성능 문제를 일으킵니다.
2. 인덱스(Index) 최적화
2.1 인덱스란?
인덱스는 책의 목차처럼, 특정 컬럼에 대한 데이터의 위치를 빠르게 찾아주는 데이터 구조입니다. 일반적으로 B-Tree 또는 Hash 기반으로 구현됩니다.
2.2 인덱스 적용 사례
Case 1: WHERE 조건에 인덱스 적용
문제: 아래와 같은 쿼리를 실행할 때 성능이 느려짐.
SELECT *
FROM employees
WHERE last_name = 'Smith';
해결 방법:
last_name 컬럼에 인덱스를 추가하면 검색 속도가 대폭 향상됩니다.
CREATE INDEX idx_last_name ON employees(last_name);
결과: 테이블 전체를 스캔하지 않고, 인덱스를 통해 필요한 데이터만 빠르게 조회.
Case 2: JOIN에 필요한 인덱스 추가
문제: 두 테이블 간 JOIN 쿼리가 느림.
SELECT e.name, d.department_name
FROM employees e
JOIN departments d
ON e.department_id = d.id;
해결 방법:
employees.department_id와 departments.id 컬럼에 인덱스를 추가.
CREATE INDEX idx_department_id ON employees(department_id);
CREATE INDEX idx_id ON departments(id);
결과: JOIN 조건에 맞는 데이터만 빠르게 조회 가능.
Case 3: 복합 인덱스 사용
문제: WHERE 조건에 여러 컬럼이 포함된 경우.
SELECT *
FROM employees
WHERE first_name = 'John' AND last_name = 'Smith';
해결 방법:
단일 인덱스 대신 복합 인덱스를 생성.
CREATE INDEX idx_name ON employees(first_name, last_name);
결과: 두 조건을 동시에 고려한 검색이 최적화.
2.3 인덱스 최적화 주의사항
• 너무 많은 인덱스는 성능을 저하시킬 수 있습니다. (데이터 삽입/업데이트 시 오버헤드 발생)
• 사용하지 않는 인덱스는 정기적으로 제거.
• EXPLAIN 명령어를 사용해 인덱스 사용 여부 확인.
3. 쿼리(Query) 최적화
3.1 불필요한 SELECT 제거
문제: 모든 컬럼을 조회하는 SELECT *는 불필요한 데이터를 처리하게 만듦.
SELECT * FROM employees;
해결 방법: 필요한 컬럼만 명시적으로 지정.
SELECT name, age FROM employees;
3.2 서브쿼리 대신 JOIN 사용
문제: 서브쿼리가 중첩되면 성능이 저하됨.
SELECT name
FROM employees
WHERE department_id = (SELECT id FROM departments WHERE department_name = 'HR');
해결 방법: JOIN으로 변환.
SELECT e.name
FROM employees e
JOIN departments d
ON e.department_id = d.id
WHERE d.department_name = 'HR';
3.3 LIMIT과 OFFSET 활용
문제: 대량의 데이터를 한 번에 조회하려다 성능 저하.
SELECT * FROM employees;
해결 방법: 한 번에 처리할 데이터 수를 제한.
SELECT * FROM employees LIMIT 100 OFFSET 0;
3.4 GROUP BY와 HAVING 최적화
문제: 그룹화된 데이터를 필터링할 때 불필요한 연산.
SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;
해결 방법: WHERE 절로 먼저 필터링.
SELECT department_id, COUNT(*)
FROM employees
WHERE hire_date > '2020-01-01'
GROUP BY department_id
HAVING COUNT(*) > 5;
4. 실제 사례: 성능 개선
현업에서 발생한 성능 개선과 관련한 실제 사례는 다음에 따로 글을 작성해서 공유하겠습니다.
2025.01.12 - [개발 지식/데이터베이스] - DB 성능 튜닝 | 300만 건 이상의 데이터에서 페이지네이션 성능 개선
5. EXPLAIN으로 쿼리 성능 분석
MariaDB, MySQL 등에서 EXPLAIN 명령어를 사용하면 쿼리 실행 계획을 확인할 수 있습니다.
--MariaDB, MySQL
EXPLAIN SELECT * FROM employees WHERE last_name = 'Smith';
--Oracle
EXPLAIN PLAN FOR SELECT * FROM employees WHERE last_name = 'Smith';
6. 결론
데이터베이스 성능 튜닝은 인덱스와 쿼리 최적화를 통해 큰 성능 개선 효과를 얻을 수 있습니다. 중요한 점은 문제의 원인을 파악하고, 최적화 작업이 과도하지 않도록 균형을 유지하는 것입니다. 실무에서 성능 문제가 발생했을 때, 이 글의 내용을 참고해 해결해 보세요.
'개발 지식 > 데이터베이스' 카테고리의 다른 글
SQL 성능 튜닝 기본 개념 | Explain Plan 사용법 (0) | 2025.02.12 |
---|---|
DELETE, DROP, TRUNCATE 비교 | 어떤 상황에서 사용해야 할까? (0) | 2025.01.21 |
데이터베이스 성능의 핵심 | 인덱스와 복합 인덱스란 무엇인가? (0) | 2025.01.13 |
DB 성능 튜닝 | 300만 건 이상의 데이터에서 페이지네이션 성능 개선 (0) | 2025.01.12 |
SQL vs NoSQL (0) | 2025.01.08 |
- Total
- Today
- Yesterday
- SQL
- 데이터베이스
- 기술면접
- 인덱스
- db성능개선
- 개발지식
- 개발
- db
- 개발기
- 역직렬화
- readtracker
- Ai
- 확장프로그램
- vimium
- 디스크사용량
- read-tracker
- 쿼리최적화
- 쿼리튜닝
- setter
- 개발자
- 크롬
- NoSQL
- 삭제쿼리
- 쿼리
- 진행률
- 페이지네이션
- keyset
- 데이터베이스삭제
- 개발자면접
- grammarly
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |