earthkingman / 42Swim

42서울 QnA 서비스
14 stars 3 forks source link

다른 유저 프로필 조회 API 구현 방식에 따른 속도 테스트 #278

Open hainho opened 2 years ago

hainho commented 2 years ago

제목

다른 유저 프로필 조회 API 구현 방식에 따른 속도 테스트

273

이슈에 대한 설명

다른 유저 프로필 조회 API 를 2가지 방식으로 구현했습니다. https://github.com/earthkingman/NodeJS-React-42StackOverFlow/wiki/%EB%8B%A4%EB%A5%B8-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C 두 방식의 차이는 ji-park님이 위 링크에 자세히 정리해주셨습니다

두 방식의 속도 차이를 측정하기 위해 2가지 데이터를 준비했습니다

스크린샷 2021-12-09 오후 9 05 20 스크린샷 2021-12-09 오후 9 07 27

user 1 은 질문 4000개 답변 2000개 댓글 1만개 고인물입니다.

스크린샷 2021-12-09 오후 9 31 31

user 2 는 질문 2개 답변 10개 댓글 15개 뉴비입니다.

스크린샷 2021-12-09 오후 9 31 48

유저를 3중 조인한 뒤 length를 계산하는 코드는 A 카운트하는 쿼리를 3번 더 날리는 코드는 B

A-user1

스크린샷 2021-12-09 오후 9 24 23 스크린샷 2021-12-09 오후 9 21 48 스크린샷 2021-12-09 오후 9 21 58

응답이 늦어 결국 서버가 죽었습니다.

async getUserProfile(userId: number) {
        const user = await this.userRepository
            .createQueryBuilder('user')
            .innerJoin('user.question', 'question')
            .innerJoin('user.answer', 'answer')
            .innerJoin('user.comment', 'comment')
            .where('user.id = :userId', { userId })
            .select(['user.id', 'user.nickname', 'user.email', 'user.photo', 'user.liked_count', 'question.id', 'answer.id', 'comment.id'])
            .getOne();

        const userProfile = {
            user: user,
            questionCount: user.question.length,
            answerCount: user.answer.length,
            commentCount: user.comment.length
        };
        return userProfile;
    }

select 의 문제인가 싶어 innerjoinandselect 대신 select에 조인한 데이터의 id만 명시해줬습니다만 결과는 같았습니다.

A-user2 20~30ms

스크린샷 2021-12-09 오후 9 22 36

B-user1 20~30ms

스크린샷 2021-12-09 오후 9 12 37

B-user2 18~25ms

스크린샷 2021-12-09 오후 9 13 01

예상했던 결과 : 쿼리를 여러번 날리는 B가 더 느릴 것이라 예상

실제 결과 : 많은 데이터에서는 B가 비교 불가능한 수준으로 빨랐고, 적은 데이터에서 또한 B가 빨랐습니다.

결론 : count를 위해서는 select후 length가 아닌 count 연산을 사용하는 것이 필수입니다.

checkList

주의사항