[PostgreSQL] 인덱스(Index)의 기초 이해하기
2024. 11. 14. 21:30ㆍRDBMS
서론
안녕하세요! 오늘은 PostgreSQL에서 매우 중요한 개념인 인덱스(Index)에 대해 알아보려고 합니다. 데이터베이스 성능 최적화에 있어 인덱스는 정말 중요한 요소인데요, 어떤 경우에 필요하고 어떻게 동작하는지 자세히 살펴보겠습니다.
1. 인덱스의 필요성
책을 읽을 때 목차가 없다고 상상해보세요. 특정 내용을 찾으려면 처음부터 끝까지 다 훑어봐야 하겠죠? 데이터베이스도 마찬가지입니다.
인덱스가 없을 때의 문제점
-- 인덱스가 없는 상황에서의 검색
SELECT * FROM users WHERE email = 'user@example.com';
이 쿼리는 테이블의 모든 row를 확인해야 합니다(Full Table Scan). 데이터가 많아질수록 성능은 급격히 저하됩니다.
인덱스의 장점
- 검색 속도 향상
- ORDER BY 연산 최적화
- 중복 값 제어 (UNIQUE 인덱스의 경우)
2. 인덱스의 종류
PostgreSQL은 다양한 종류의 인덱스를 제공합니다.
B-tree 인덱스
가장 일반적으로 사용되는 인덱스입니다.
-- 기본 B-tree 인덱스 생성
CREATE INDEX idx_user_email ON users(email);
Hash 인덱스
동등 비교(=)에만 사용됩니다.
-- Hash 인덱스 생성
CREATE INDEX idx_user_id_hash ON users USING HASH (user_id);
GiST 인덱스
지리 데이터나 기하 데이터에 적합합니다.
-- GiST 인덱스 생성 예시
CREATE INDEX idx_location ON cities USING GIST (location);
GIN 인덱스
배열이나 전문 검색에 사용됩니다.
-- 전문 검색을 위한 GIN 인덱스
CREATE INDEX idx_document_text ON documents USING GIN (to_tsvector('english', content));
3. 인덱스 동작 원리
기본 동작 방식
-- 예시 테이블
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255),
name VARCHAR(100)
);
-- 인덱스 생성
CREATE INDEX idx_user_email ON users(email);
인덱스는 다음과 같은 과정으로 동작합니다:
- 인덱스 생성 시
- 지정된 컬럼의 값들을 정렬
- 정렬된 값과 실제 레코드의 위치 정보를 저장
- 쿼리 실행 시
- 인덱스에서 'test@example.com' 값을 검색
- 해당 값의 위치 정보를 사용해 실제 레코드 접근
SELECT * FROM users WHERE email = 'test@example.com';
실행 계획으로 확인하기
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'test@example.com';
Index Scan using idx_user_email on users
Index Cond: (email = 'test@example.com'::text)
...
주의할 점
- 인덱스도 공짜가 아닙니다
- 저장 공간을 차지합니다
- INSERT, UPDATE, DELETE 시 추가 작업이 필요합니다
- 모든 컬럼에 인덱스를 생성하는 것은 좋지 않습니다
- 데이터 변경이 자주 일어나는 컬럼
- 선택도(Selectivity)가 낮은 컬럼
- 정기적인 관리가 필요합니다
```sql
-- 인덱스 재구축
REINDEX INDEX idx_user_email;
-- 사용되지 않는 인덱스 확인
SELECT * FROM pg_stat_user_indexes;
```
마치며
인덱스는 데이터베이스 성능 최적화의 핵심입니다. 하지만 무조건 많이 만든다고 좋은 것이 아니라, 적절한 상황에 적절한 타입의 인덱스를 사용하는 것이 중요합니다. 특히 프로덕션 환경에서는 인덱스 생성 전에 항상 실행 계획을 확인하고, 성능 테스트를 해보는 것이 좋습니다.
다음에는 조금 다른 종류의 인덱스에 대해 다뤄보도록 하겠습니다. 감사합니다! 😊
'RDBMS' 카테고리의 다른 글
[PostgreSQL] Vector Search를 위한 인덱스 타입 비교 (HNSW vs IVFFlat) (0) | 2024.11.14 |
---|---|
[AWS Redshift] FULL JOIN과 COALESCE (0) | 2024.03.08 |
MSSQL - DataBase내부 테이블들의 용량/row수 확인하기 (0) | 2022.05.07 |
MSSQL - 날짜 및 시간 더하고 빼기 (0) | 2022.01.04 |
MSSQL - 현재 날짜 시간 구하기 (0) | 2022.01.04 |