성능테스트/성능 개선

데이터베이스 인덱싱과 쓰기 성능 테스트

dongzzirit 2024. 12. 18. 16:51

데이터베이스 성능 최적화에서 인덱싱은 빠른 조회 속도를 보장하는 중요한 도구입니다. 하지만 인덱스를 많이 생성하면 쓰기 작업(INSERT, UPDATE, DELETE)의 성능이 저하된다고 알려져 있습니다. 이번 글에서는 실제 실험 데이터를 기반으로 이 가정을 테스트한 결과를 공유합니다.


1. 테스트 목적

멀티 컬럼 인덱스와 단일 컬럼 인덱스를 다수 적용했을 때, 쓰기 작업의 성능이 얼마나 저하되는지 확인하는 것이 목적이었습니다. 특히, 데이터베이스에 110만 건 이상의 데이터를 넣고 쓰기 작업을 수행하며, 인덱스가 없는 상태와 있는 상태를 비교해 보았습니다.


2. 테스트 환경

  • 데이터베이스: MySQL 8.0
  • 테이블: Customer 테이블
  • 데이터 크기: 약 110만 건
  • 인덱스 설정:
    • 테스트 A: 기본 키 외에 추가 인덱스 없음
    • 테스트 B: 복합 인덱스 2개 적용
CREATE INDEX idx_customer_name_email ON customer(name, email);
CREATE INDEX idx_customer_phone_grade ON customer(phone, grade);

 

  • 테스트 도구: Artillery를 사용한 부하 테스트
  • 테스트 작업:
    • INSERT: 고객 데이터 삽입
    • UPDATE: 고객 데이터 수정
    • DELETE: 고객 데이터 삭제

3. 테스트 시나리오 및 데이터

요청 예시

config:
  target: 'http://localhost:8080'
  phases:
    - duration: 10
      arrivalRate: 10
    - duration: 20
      arrivalRate: 20
    - duration: 30
      arrivalRate: 30
    - duration: 20
      arrivalRate: 10

scenarios:
  - flow:
      # 1. 로그인 후 토큰 획득
      - post:
          url: "/api/v1/auth/signintest"
          json:
            email: "test2@gmail.com"
            password: "123456789"
          capture:
            - json: "$.data.atk"
              as: "authToken"

      # 2. 고객 정보 수정 (쓰기 작업)
      - patch:
          url: "/api/v1/customers/1000"
          headers:
            Authorization: "Bearer {{ authToken }}"
          json:
            name: "Updated Name {{ $randomInt }}"
            phone: "010-{{ $randomInt }}-{{ $randomInt }}"

      # 3. 고객 삭제 (쓰기 작업)
      - delete:
          url: "/api/v1/customers/{{ $randomInt }}"
          headers:
            Authorization: "Bearer {{ authToken }}"

      # 4. 고객 메모 작성/수정 (쓰기 작업)
      - put:
          url: "/api/v1/customers/100/memo"
          headers:
            Authorization: "Bearer {{ authToken }}"
          json:
            content: "This is a test memo with random value {{ $randomInt }}."
            title: "Test Memo Title {{ $randomInt }}"

 


4. 테스트 결과

1. 지연 시간(Latency) 비교

지표 첫 번째 결과 (인덱스 없음) 두 번째 결과 (인덱스 있음)

최소 지연 시간 (min) 0 ms 0 ms
최대 지연 시간 (max) 109 ms 391 ms
중앙값 (median) 1 ms 2 ms
95퍼센타일 (p95) 77 ms 77 ms
99퍼센타일 (p99) 79 ms 80 ms

분석

  • 최소 지연 시간은 두 결과 모두 동일합니다 (0 ms).
  • 최대 지연 시간에서 큰 차이가 나타납니다:
    • 인덱스가 있는 경우 최대 지연 시간은 391 ms.
    • 인덱스가 없는 경우 최대 지연 시간은 109 ms.
  • 중앙값에서 인덱스가 있는 경우 2 ms, 없는 경우 1 ms로 차이가 있습니다.
  • 95% 및 99% 지연 시간은 거의 동일하게 나타났습니다.

5. 결론

멀티 컬럼 인덱스를 적용하면 최대 지연 시간이 늘어났다는 것을 알았지만 지금 테스트가 뭔가 이상한 거 같아서 다시 한번 검토가 필요한 거 같습니다.