Skip to content

Week4 Backend

Seonmi Park edited this page Aug 23, 2023 · 9 revisions

Sprint 4

  • API 개발 끝
  • 쿼리 성능 개선 중
  • 더미데이터 생성(판매: 100만 건, 판매한 옵션들: 350만 건)

쿼리 성능 개선

SELECT *
FROM (SELECT so.additional_option_id AS id,
             COUNT(*)                AS select_count
      FROM (SELECT *
            FROM SALES
            WHERE model_id IN
                  (SELECT id
                   FROM MODEL
                   WHERE trim_id = 1)) s
               JOIN SALES_OPTIONS so ON s.id = so.sales_id
      WHERE 9 IN (s.tag1, s.tag2, s.tag3)
      GROUP BY so.additional_option_id
      WITH ROLLUP) AS count_table
WHERE id = 130
   OR id IS NULL

50초 나오던 쿼리 Sales_Options(sales_id, additional_option_id) 인덱스 생성 해서 1.5 ~ 3초대로 줄임

with joined as (select {0}, age, gender, tag1, tag2, tag3
                from SALES s
                         join MODEL m on s.model_id = m.id
                where m.trim_id = 1
                )

select {0}       as id,
       count({0}) as select_count
from joined
WHERE (
            (:tag1, :tag2, :tag3) in ((tag1, tag2, tag3),
                                      (tag1, tag3, tag2),
                                      (tag2, tag1, tag3),
                                      (tag2, tag3, tag1),
                                      (tag3, tag1, tag2),
                                      (tag3, tag2, tag1)
            )
        and (
                    (:age <= age <= :age+9 and gender != :gender)
                    or ((:age < age or age >= :age+9) and gender = :gender)
                    or (:age <= age < :age+9 and gender = :gender)
                )
    )
   or (
                    :age <= age < :age+9
        and gender = :gender
        and (
                            (:tag1, :tag2) in ((tag1, tag2), (tag1, tag3),
                                               (tag2, tag1), (tag2, tag3),
                                               (tag3, tag1), (tag3, tag2))
                        or
                            (:tag1, :tag3) in ((tag1, tag2), (tag1, tag3),
                                               (tag2, tag1), (tag2, tag3),
                                               (tag3, tag1), (tag3, tag2))
                        or
                            (:tag2, :tag3) in ((tag1, tag2), (tag1, tag3),
                                               (tag2, tag1), (tag2, tag3),
                                               (tag3, tag1), (tag3, tag2))
                    )
        and (:tag1, :tag2, :tag3) not in (
                                          (tag1, tag2, tag3),
                                          (tag1, tag3, tag2),
                                          (tag2, tag1, tag3),
                                          (tag2, tag3, tag1),
                                          (tag3, tag1, tag2),
                                          (tag3, tag2, tag1)
        )
    )
group by :targetId
with rollup

분명 카디널리티가 높은 컬럼으로 인덱싱을 거는 게 맞다고 배웠는데 왜 값이 세 개인 gender로 만든 인덱스가 실행 계획으로 선정되고, 실행될까...

서버 성능 개선

4주차 이전까지는 간단한 단순 조회문 위주였다. 그래서 성능 상 문제를 발견하지 못했다.

가이드모드 (추천 알고리즘) API를 연결하는 작업하면서 ec2 CPU 사용량이 급격하게 증가했고, 급기야 DB 서버가 터지기도 했다. image

월요일(8/21)부터 ec2가 계속 죽는다... cpu 사용률이 급증한다 계속ㅠㅠ db server + spring server swap로 메모리 늘리기

image image
  • 무중단 배포 설정하면서 docker-compose.yml에 작성한 코드가 문제라는 걸 알았다. restart-always 설정을 해놨었다. Redis config 설정 관련해서 오류가 발생했는데, 계속 요청을 해서 CPU 사용률이 200%까지 올라갔던 것이다. Docker에서 localhost를 접근하는 데 문제가 발생해서 Redis를 다른 인스턴스로 빼니까 문제가 해결된 것이다. 내가 던진 작은 공......