안녕하세요. 그님스 백엔드 유민우입니다!
오늘은 유저 검색하기 부분을 만들면서
검색부분이 어떻게 발전해왔는지 적어볼까합니다.
우선 유저 이름으로 검색했을 때, 조회 될 것은
유저Id, 유저이름, 유저프로필이미지,
그리고 현재 로그인 한 유저가 검색된 유저를 팔로우 했는지 여부였습니다.
(+ 로그인한 본인의 이름은 안나오게)

ERD를 보시면 아시겠지만 유저와
팔로우의 테이블이 따로 되어있습니다.
1)

JPA를 이용한 첫번째 방법이었습니다.
이 코드를 들여다 보면...
1. username으로 매칭되는 이름들을 모두 찾고
2. myName으로 로그인한 본인의 이름은 안나오게 했으며
3. Pageble 매개변수를 활용하여 페이징 처리까지 해주었습니다.
결과는 ...

검색어 '유'로 최대 1000개의 데이터 조회

잘 검색된 것을 볼 수 있습니다.
(이름이 다 '유민우'인 것은 더미 데이터 이름을 전부 '유민우'로
해서 그렇습니다...Id가 모두 다르니 그것을 보면 됩니다!)
검색은 잘 됬지만 내부적으로 보면
유저 정보를 검색했는데 어떻게 팔로우 여부까지
boolean값으로 잘 나왔을까요?

구현된 함수를 보시면 아시겠지만...
findAllByUsernameLikeAndUsernameIsNot() 메서드로 찾아온
결과값을 for 문으로 돌리는 코드가 실행이 되고있습니다.
그렇다면 방금의 1000개의 데이터를 조회하기 위해서
쿼리가 몇번이 날아갔을까요?

오른쪽의 스크롤을 보시면
쿼리가 엄~청 많이 날라간 것을 볼 수 있습니다.
(clear 하고 누른 것...)
2)
1)의 문제를 해결하기 위해
쿼리를 직접 짜서 최적화를 해보았습니다.

이 쿼리를 짜면서 고려한 점은
1. 로그인한 본인의 이름은 검색 안됨
2. like를 이용한 유저 검색
3. Friendship 테이블을 join하면서 조건을
(팔로우 신청 한사람 = 로그인 한 사람)
case 문을 사용하여 바로 팔로우 여부를 boolean 값으로 넣어 주었습니다.
결과는 ...

이렇게 1)과 똑같이 잘 나온 것을 볼 수 있고
시간도 잘 보면 125ms -> 11ms
쿼리를 보면...

토큰 검증 부분을 제외하면
쿼리가 한번만 나간 것을 볼 수 있습니다.
(스크롤 바가 뜨지도 않음 good)
이렇게 해결이 된 줄 알았으나...

프론트 분들과 맞춰본 후 QA 과정에서
동일 인물이 여러번 나오는 에러가 발생했습니다.
(저기서 '유민우'는 모두 같은사람)
3)
갑작스러운 문제에 백엔드 팀원분들과
왜 이런 문제가 나왔을까 생각해보다
Freindship을 join 하는 과정에서
문제가 생겼다고 결론이 나왔습니다.
그래서 쿼리를 보면서 고민하다보니
(팔로우 신청한 사람 = 로그인 한 사람) 이라는 조건을 했는데
'팔로우 당한 사람'의 조건이 없어서
'로그인 한 사람'의 팔로우 수 만큼 출력이 된 것을 확인하였습니다.
(+ 본인 이름을 검색에서 제외하는 과정에서 동명이인도 같이 제외되는 것을 발견하였습니다.)

이번에 고려한 점은
2) 에서 고려한 것과 더해서
1. username 대신 id로 로그인한 유저를 검색에서 제외
2. (팔로우 당한 사람의 id = 검색된 사람의 id) 조건
결과는 .................

성공!
결과물을 보면 isFollowed가
어떤 것은 true, 어떤 것은 false 로
팔로우를 여러번 걸어놓았지만
결과물은 모두 한번씩 출력된 것을 볼 수 있습니다.

쿼리도 당연히 한번만 나간 것을 볼 수 있습니다.
결과
최적화 전


최적화 후


쿼리와 시간이 눈에 띄게 줄어든 것을 볼 수 있습니다.
유저 검색 발전 과정이었습니다.
읽어주셔서 감사합니다.
'BE 프로젝트 일대기' 카테고리의 다른 글
| Gnims - 인증 방식 (0) | 2023.03.11 |
|---|---|
| [BE] 소셜 로그인 (0) | 2023.03.09 |
| 그님스 BE는 코드 리뷰를 합니다. 그런데 잘되고 있나요...? (0) | 2023.02.26 |
| GNIMS - 수락/거절 대기중인 일정 조회 API 최적화 일대기 (0) | 2023.02.22 |
| GNIMS - 디데이 계산 방식이 변경됩니다! (0) | 2023.02.16 |