DB Index, 언제 어떻게 추가해야 쿼리 속도가 빨라질까?

데이터가 많아지면서 느려지는 Django ORM 쿼리를 인덱스로 최적화하는 방법을 학습. 인덱스의 원리부터 실무 적용까지 체계적으로 다룸

인덱스 기본 원리

인덱스가 없다면

  • 데이터베이스는 모든 행을 처음부터 끝까지 스캔하는 Full Table Scan 실행

  • 데이터가 수십만, 수백만 건으로 늘어나면 엄청난 I/O 비용 발생

인덱스란

  • 특정 컬럼의 값과 해당 행의 물리적 주소를 키-값 쌍으로 저장하는 목차

  • B-Tree 자료구조 사용으로 O(log N) 시간 복잡도 보장

  • =, BETWEEN, LIKE 'prefix%' 같은 범위 검색에도 효율적

Django에서 인덱스 추가 방법

단일 컬럼 인덱스

class Post(models.Model):
    status = models.CharField(max_length=10, db_index=True)

다중 컬럼 인덱스 및 고급 옵션

class Product(models.Model):
    category = models.ForeignKey('Category', on_delete=models.PROTECT)
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)

    class Meta:
        indexes = [
            models.Index(fields=['category', '-price']),  # 다중 컬럼
            models.Index(fields=['name']),                # 단일 컬럼
        ]

인덱스 추가 시점

상황
대상
Django ORM 예시

WHERE 절

filter(), exclude(), get() 조건 컬럼

Post.objects.filter(status='published')

JOIN

ForeignKey, OneToOneField 키 컬럼

Post.objects.filter(author__name='User')

ORDER BY 절

order_by() 정렬 기준 컬럼

Post.objects.order_by('-created_at')

GROUP BY 절

annotate()와 values() 그룹화 기준

Sale.objects.values('category').annotate(total=Sum('amount'))

참고: Django는 ForeignKey에 자동으로 인덱스 생성

인덱싱 전략

다중 컬럼 인덱스 순서

  • Index(fields=['A', 'B'])WHERE A = ?WHERE A = ? AND B = ?에만 효과

  • WHERE B = ?에는 효과 없음

  • 가장 선택도가 높고 자주 사용되는 컬럼을 맨 앞에 배치

커버링 인덱스

  • 쿼리에 필요한 모든 정보를 인덱스가 포함

  • 실제 테이블 접근 없이 인덱스 스캔만으로 결과 반환

  • 테이블 접근 I/O가 완전히 사라져 매우 빠른 성능

주의사항

성능 트레이드오프

  • 조회(SELECT) 성능 향상 vs 생성/수정/삭제(INSERT/UPDATE/DELETE) 성능 저하

  • 인덱스가 많을수록 CUD 작업 속도 감소

  • 추가 저장 공간 필요

비효율적인 경우

  • LIKE '%word' (앞부분 와일드카드)

  • WHERE status != 'active' (부정형 조건)

  • 카디널리티가 낮은 컬럼 (성별, boolean 값 등)

  • 사용되지 않는 인덱스는 리소스 낭비

성능 개선 프로세스

  1. 느린 API 엔드포인트 발견

  2. django-debug-toolbar로 느린 SQL 쿼리 특정

  3. EXPLAIN ANALYZE로 실행 계획 분석

  4. Seq Scan(Full Scan) 확인시 적절한 인덱스 설계

  5. 마이그레이션 실행 후 Index Scan으로 변경 확인

EXPLAIN ANALYZE 활용

  • 쿼리 실행 계획과 실제 실행 시간 확인

  • Seq Scan → Index Scan 변경으로 성능 개선 검증

  • 실행 시간 단축 효과 측정

Last updated