SPRING

[SPRING] 뉴스피드 인덱스 실전 테스트

도원좀비 2025. 4. 13. 17:05

🔗 실험 배경

이전 포스트에서 updated_at, created_at, title 기준으로 인덱스를 생성하여 단일 조건 기반 조회 성능을 개선한 바 있습니다.

 

이번에는 실전에서 사용하는 쿼리를 사용해서 실험해보려고 합니다.

실전 호출 api : GET  http://localhost:8080/api/feeds?keyword=더미&page=0&size=10


🧪 1차 실험 조건

실험 항목 조건
더미 데이터 10000건
정렬 기준 updated_at DESC
조인 좋아요, 댓글, 이미지, 유저
시행 횟수 10회

쿼리문 :

SELECT nf.id,
       u.id                   AS user_id,
       u.nickname,
       nf.title,
       nf.content,
       nf.updated_at,
       COUNT(DISTINCT nfl.id) AS like_count,
       COUNT(DISTINCT c.id)   AS comment_count,
       MIN(f.path)            AS thumbnail,
       nf.view_count
FROM news_feeds nf
         LEFT JOIN news_feed_likes nfl ON nf.id = nfl.news_feeds_id
         LEFT JOIN comments c ON nf.id = c.news_feed_id
         LEFT JOIN news_files f ON nf.id = f.news_feed_id
         JOIN users u ON nf.user_id = u.id
WHERE nf.deleted_at IS NULL
  AND (nf.title LIKE '%더미%' OR nf.content LIKE '%더미%')
  AND nf.updated_at BETWEEN '2025-04-01 00:00:00' AND '2025-05-31 23:59:59'
GROUP BY nf.id, u.id, u.nickname, nf.title, nf.content, nf.updated_at, nf.view_count
ORDER BY nf.updated_at DESC;

📊 1차 실험 결과

실험 유형 총 평균 시간(ms) Execution 평균 (ms) Fetching 평균 (ms) 최소~최대 시간 (ms)
인덱스 없음 321.6 140.6 181.0 183 ~ 476
단일 인덱스
(updated_at)
307.7 139.8 167.9 183 ~472
복합 인덱스
(title, updated_at)
300.9 138.5 162.4 182 ~461
최적화 인덱스
(title, updated_at, deleted_at)
260.6 133.4 127.2 182 ~ 396

 

기대한 만큼 성능의 개선이 나오지 않음


🤔 개선이 미미한 원인

1️⃣ LIKE '%더미%' 패턴 검색의 인덱스 무력화

2️⃣ GROUP BY 대상 컬럼이 너무 많고 JOIN이 많음


🧪 2 실험 조건

실험 항목 조건
더미 데이터 1,000,000건
검색 조건 LIKE vs MATCH
정렬 기준 updated_at DESC
조인 좋아요, 댓글, 이미지, 유저
시행 횟수 10회
더보기

 

SELECT nf.id,
       u.id                   AS user_id,
       u.nickname,
       nf.title,
       nf.content,
       nf.updated_at,
       COUNT(DISTINCT nfl.id) AS like_count,
       COUNT(DISTINCT c.id)   AS comment_count,
       MIN(f.path)            AS thumbnail,
       nf.view_count
FROM news_feeds nf
         LEFT JOIN news_feed_likes nfl ON nf.id = nfl.news_feeds_id
         LEFT JOIN comments c ON nf.id = c.news_feed_id
         LEFT JOIN news_files f ON nf.id = f.news_feed_id
         JOIN users u ON nf.user_id = u.id
WHERE nf.deleted_at IS NULL
  AND (nf.title LIKE '%더미%' OR nf.content LIKE '%더미%')
  AND nf.updated_at >= '2025-04-01 00:00:00'
  AND nf.updated_at <= '2025-05-31 23:59:59'
GROUP BY nf.id, u.id, u.nickname, nf.title, nf.content, nf.updated_at, nf.view_count
ORDER BY nf.updated_at DESC;

SELECT nf.id,
       u.id                   AS user_id,
       u.nickname,
       nf.title,
       nf.content,
       nf.updated_at,
       COUNT(DISTINCT nfl.id) AS like_count,
       COUNT(DISTINCT c.id)   AS comment_count,
       MIN(f.path)            AS thumbnail,
       nf.view_count
FROM news_feeds nf
         LEFT JOIN news_feed_likes nfl ON nf.id = nfl.news_feeds_id
         LEFT JOIN comments c ON nf.id = c.news_feed_id
         LEFT JOIN news_files f ON nf.id = f.news_feed_id
         JOIN users u ON nf.user_id = u.id
WHERE nf.deleted_at IS NULL
  AND MATCH(nf.title, nf.content) AGAINST('+더미' IN BOOLEAN MODE)
  AND nf.updated_at BETWEEN '2025-04-01 00:00:00' AND '2025-05-31 23:59:59'
GROUP BY nf.id, u.id, u.nickname, nf.title, nf.content, nf.updated_at, nf.view_count
ORDER BY nf.updated_at DESC;

📊 실험 결과 요약

실험 조건(10회) 평균 실행 시간 (초) 개선율 (기준: 기본 인덱스)
기본 인덱스(PK, FK만) 11.5s -
복합 인덱스 (title, content, updated_at, deleted_at) 7.6s 🔽 약 33.9% 향상
MATCH 사용 (FULLTEXT 인덱스, ft_min_word_len=2) 13.6s 🔺 약 18.3% 느려짐

🔍 분석

  • LIKE 조건에서는 복합 인덱스(title, content, updated_at, deleted_at)가 명확한 성능 향상을 보임
  • MATCH 사용 시, 오히려 실행 시간이 증가
    • 이는 MATCH가 FULLTEXT 인덱스를 사용하더라도 JOIN + GROUP BY가 복잡한 경우에는 오히려 오버헤드가 발생함을 의미
    • 또한, BOOLEAN MODE를 쓰더라도 결과 필터링에 따른 로우 수 증가가 성능 저하로 이어졌을 가능성 존재

✅ 결론

  • 복잡한 조인/필터/정렬 조건이 포함된 실사용 쿼리에서는 FULLTEXT MATCH보다는 복합 인덱스 + LIKE 조건이 더 효과적
  • 인덱스 구성은 단순 조건 필터링에만 초점을 둘 것이 아니라, 정렬 기준과 함께 설계하는 것이 중요함
  • 쿼리 튜닝은 무조건 MATCH → LIKE보다 빠르다는 통념을 다시 생각해볼 필요가 있음

'SPRING' 카테고리의 다른 글

[SPRING] 트랜잭션(Transaction)  (2) 2025.04.17
[SPRING] 인터셉터 AOP  (1) 2025.04.15
[SPRING] 뉴스피드 과제 인덱스 성능 실험  (1) 2025.04.13
[Spring] 스프링 테스트 코드  (3) 2025.04.10
[Spring] 인덱싱  (0) 2025.04.09