대머리개발자

게시판 코드에서...고민s 본문

개발이야기/DataBase

게시판 코드에서...고민s

대머리개발자 2023. 10. 24. 19:19
728x90

 

서브쿼리? 조인쿼리?

늘 고민인데.... 사실 고민할 거리가 없다. 조인 쿼리로 할 수 있으면 무조건 조인 쿼리로 가야 한다. 성능적인면에서...

근데 왜 고민해?... 서브쿼리가 개발하기는 편하거든.. ㅠ

 

 

좋아요/조회수를 가져오는 쿼리에 대한 고민. ㅎ

 

## 서브 쿼리

필터된 친구만 스칼라 서브 쿼리!!! 리스트 사이즈를 50개로 늘리면 50*2개(좋아요/조회수) = 100번의 서브 쿼리가 슝슝슝!!

 

## 조인의 경우

방법 1 : 조인을 하고 집약을 한다.

방법 2 : 집약을 하고 조인을 한다.

 

느낌이 와야 한데이.?

https://schatz37.tistory.com/3

 

JPA는 from절에 서브 쿼리를 지원하지 않는다. 해서 네이티브 쿼리로 진행해야 한다.

    @Query(nativeQuery = true,
        value = """
                    select id, title, menuId, userId, nickname, regDt, ifnull(viewCnt, 0) viewCount, ifnull(goodCnt,0) goodCount  from Board
                    left outer join (
                        select targetId,
                             sum(if(type = 1,  1, 0) ) as viewCnt
                            ,sum(if(type = 2,  1, 0) ) as goodCnt
                    from  countstat c group by targetId
                    ) c on board.id = c.targetId
                    where board.status = 'A' 
                    and menuId = :menuId
                    order by groupId desc, path asc
                    limit :pageIndex , :pageSize
                """
    )
    fun searchBoard(menuId:Int, pageIndex:Long, pageSize:Long): MutableList<BoardListDtoAble>?

또 하나 체크할 부분이 단순 BoardListDto가 아니다. DTO로 진행하면...에러가 슝슝 떨어진다.

만약 DTO가 아니라 엔티티로 바인딩한다면.. 모든 컬럼을 명시해야 한다. ^^.. 그렇지 않으면 에러가 슝슝슝!

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type

서브쿼리는..깔끔스하지만...

fun search(searchInfo: SearchInfo): MutableList<BoardListDto>? {
        return jpaQueryFactory
            .select(
                Projections.bean(BoardListDto::class.java
                                ,qBoard.id
                                ,qBoard.title
                                ,qBoard.menuId
                                ,qBoard.userId
                                ,qBoard.nickname
                                ,qBoard.noticeType
                                ,qBoard.regDt
                                ,  ExpressionUtils.`as`( JPAExpressions
                                    .select(QCountStat.countStat.type.count())
                                    .from(QCountStat.countStat)
                                    .where(QCountStat.countStat.targetId.eq(qBoard.id), QCountStat.countStat.type.eq(1)), "viewCount")
                                , ExpressionUtils.`as`( JPAExpressions
                                    .select( QCountStat.countStat.type.count())
                                    .from(QCountStat.countStat)
                                    .where(QCountStat.countStat.targetId.eq(qBoard.id), QCountStat.countStat.type.eq(2)), "goodCount")
                                )
            )
            .from(QBoard.board)
            .where(QBoard.board.status.eq(Board.STATUS_ACTIVE))
            .orderBy(QBoard.board.groupId.desc())
            .orderBy(QBoard.board.path.asc())
            .offset(searchInfo.filter!!.pageIndex)
            .limit(searchInfo.filter!!.pageSize)
            .fetch()
    }

 

게시판 3만건에서 20개의 리스트(각 리스트마다 좋아요/조회수는 각 1백개)를 조회하는 쿼리는 차이는  

조인 평균 : 0.04ms

서브 쿼리 평균 : 0.06ms

보는거와 같이 100분의 2초이지만

 

퍼센트(%)로 따지면 33.3%차이나는 부분이다.... 데이터가 더더욱 많아진다면......더더욱 체감 할 수 있을듯 하다.

 

 

 

좋으다!.

https://www.youtube.com/watch?v=zMAX7g6rO_Y&t=769s

 

 

 

728x90

'개발이야기 > DataBase' 카테고리의 다른 글

Mysql + R2DBC 쿼리 로그  (0) 2024.01.25
mysql json type  (1) 2024.01.05
[R2DBC] 바인딩  (0) 2023.09.13
R2DBC ...불행의 시작...(2)  (0) 2023.06.09
R2DBC ...불행의 시작...  (1) 2023.04.12