te___ho
NO RULES
te___ho
전체 방문자
오늘
어제
  • 분류 전체보기 (92)
    • 주니어의 개발일지 (1)
    • My project (29)
      • High Traffic Lab (5)
      • Nanaland in Jeju (8)
      • Univey (3)
      • inflearn_clone? (13)
    • Spring (19)
    • Network & CS (9)
    • Java (1)
    • Front_End (8)
    • Algorithm (11)
    • ETC (6)
    • Scribble (8)

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
te___ho

NO RULES

QueryDsl 부모에 자식 리스트 넣기 -> Transform (부제 : 쿼리의 수와 속도는 무조건 정비례가 아니다..)
My project/Nanaland in Jeju

QueryDsl 부모에 자식 리스트 넣기 -> Transform (부제 : 쿼리의 수와 속도는 무조건 정비례가 아니다..)

2024. 6. 27. 15:38

 이번 프로젝트에서는 QueryDsl을 사용하고 있다. 전 프로젝트까지만 해도 JPQL, QueryDsl을 왜 굳이 써야 하는지 감이 잡히지 않아서 Jpa method만 사용하였다. 자세한 내용은 추후 따로 글을 작성할 예정이다.

 

문제상황

웬만한 조회에서 QuerDsl을 사용하고 있었다. 하지만 문제가 발생했는데 보통은 key - value 형태로만 조회를 했다.

id : 10 , thumbnailUrl: http,,, 이런 형태

 

그런데 key - list 형태로 조회를 해와야하는 상황이 생겨버렸다. 즉 부모에 자식이 리스트 형태로 들어가야 하는 것이다.

nanaDetails가 list 형태로 들어가고 그안에 또 additionalInfoList가 들어간다.

 한 이틀동안 뇌피셜을 기반으로 여러 시도를 하다가 실패했다. 다음 작업을 해야 할 날짜가 다가와서 일단 JPA 메서드로 범벅을 해놓고 넘어갔다. 어느 정도 시간이 지나 여유가 생겨서 다시 수정을 해보려고 마음먹었다. JPA 메서드를 사용하면 안되겠다고 생각한 큰 이유가 조회할 때 쿼리가 너무 많이 발생한다.. Nana라는 카테고리의 게시물인데 Nana, NanaTitle, NanaContent 의 구조로 되어 있고 게시물 관련 쿼리 말고도 회원의 Langauge, 회원이 좋아요 누른 여부 등등등 여러 쿼리가 합쳐져서 게시물 하나 조회하는데 28개의 쿼리가 발생하고 있었다. 이건 너무 심한 것 같아서 얼른 개선 방법을 찾아보았다. 

해결방법 & 설명

 내가 최종적으로 만들어야 하는 형태는 아래와 같다. data안에 list1을 넣어야 하고 그안에 또 list2를 넣어야 한다.. 결과 먼저 말하자면 list2까지는 실패했다. 거의 일주일 동안 여러 시도를 해보았지만 결국 list 1까지만 해결했다.

// 원래의 목표
"data":{
	"key1" : "value"
   	"key2" : "value"
	"list1":[
    		"key3" : "value"
	        "key4" : "value"
    	  	"list2" : [
        			"key5" : "value"
	        		"key6" : "value"
       	 		  ]
		]
	}

// 성공 형태 (이 방법을 기준으로 설명)
"data":{
	"key1" : "value"
  	"key2" : "value"
	"list1":[
    		"key3" : "value"
	        "key4" : "value"
		]
	}

 

 결론 먼저 말하자면 transfrom이라는 것을 이용해서 부모 안에 자식 리스트를 넣을 수 있었다. 사용 방법을 우선 설명하고 코드랑 비교해보겠다.

 

1. 반환형을 Map<id자료형, 반환받을 형태> resultMap 으로 지정한다. (resultMap은 그냥 변수명 자유롭게 가능 )

2. from, join, where, orderBy 등 을 상황에 맞게 적절히 작성한다.

3. .transform(groupBy(구분 값)).as(new Q객체(key1, key2, list(new Qlist1(key3, key4))))

4. 구분 값은 구분할 수 있는 unique 값-> 보통 entity의 id, Q객체의 인자들에는원래 QueryDsl 작성하는 것처럼 작성하고       자식 리스트 부분을 list()로 감싸서 하나의 Q객체를 추가적으로 만든다. -> list(new Qlist(ke3, key4))

5. 1의 반환받을 형태가 1개의 객체라면  return resultMap.get(구분값) ,
           List라면 resultMap.keySet().stream().map(resultMap::get).collect(toList())

 

이렇게 보면 어렵지만 코드와 함께 보면 쉽게 이해할 수 있을 것이다. 나는 nana라는 객체를 상세 조회하는 쿼리이기에 transform(groupBy(구분 값)) 의 구분 값은 nana.id이다. 아래는 내가 실제 작성한 코드이다.

public NanaCompositeDto findNanaDetailById(Long nanaId, Locale locale) {
	// Long은 구분 값 nana.id의 자료형, NanaCompositeDto는 반환 타입 -> 메서드 return 형
    Map<Long, NanaCompositeDto> resultMap = queryFactory
    
    // from, join, where, orderBy 작성
        .from(nana)
        .join(nanaTitle).on(nanaTitle.nana.id.eq(nanaId))
        .join(nanaContent).on(nanaContent.nanaTitle.id.eq(nanaTitle.id))
        .join(imageFile).on(imageFile.id.eq(nanaContent.imageFile.id))
        .where(nanaTitle.language.locale.eq(locale))
        .orderBy(nanaContent.number.asc())
        
        //gropBy()에 구분 값 nana.id 작성
        // QNanaResponse_NanaCompositeDto에 List-> 자식리스트 사용.
        .transform(groupBy(nana.id).as(new QNanaResponse_NanaCompositeDto(
            nana.version,
            nanaTitle.id,
            nanaTitle.language.locale,
            nanaTitle.imageFile.originUrl,
            nanaTitle.imageFile.thumbnailUrl,
            nanaTitle.subHeading,
            nanaTitle.heading,
            nanaTitle.notice,
            list(new QNanaResponse_NanaCompositeDto_NanaContentDto(
                nanaContent.id,
                imageFile.originUrl,
                nanaContent.number,
                nanaContent.subTitle,
                nanaContent.title,
                nanaContent.content)
            )
        )));

    // resultMap에서 id에 해당하는 NanaDetailDto 반환
    // 단일 값
    return resultMap.get(nanaId);

 

 전체적으로 요약해 보자면 조회해야 할 값들을 transfrom(groupBy(nana.id).as(!여기!) as 에 넣어서 원래의 querydsl처럼 사용한다. 이때 자식 리스트가 필요하면 list(new Q객체(값 1, 값 2, 값 3,,))을 사용한다. 여기서 groupBy에 넣는 값이 이해가 되지 않을 수 있는데 메서드 전체 반환 형을 List로 했을 때의 값을 생각해 보면 쉽다. 묶을 값의 기준을 설정하는 것이다.

public List<NanaCompositeDto> findNanaDetailById(Long nanaId, Locale locale) {
	// 반환형 List로 변경, Map안에 반환형도 List로 변경
    Map<Long, List<NanaCompositeDto>> resultMap = queryFactory
    
    // from, join, where, orderBy 작성
        .from(nana)
        
        // 전의 코드와 동일해서 생략
		
         .transform(groupBy(nana.id).as(new QNanaResponse_NanaCompositeDto(
            nana.version,
            
        // 전의 코드와 동일해서 생략            
        
    // List형태로  NanaDetailDto 반환
    return resultMap.keySet().stream()
    		.map(resultMap:;get)
            .collect(toList());

/////////////////////////////////
// 결과 값
"data":[
	{ // nana id 1의 값들
	"key1" : "value"
  	"key2" : "value"
	"list1":[
    		"key3" : "value"
	        "key4" : "value"
		]
      }, // nana id 1의 값들
     
     { // nana id 2의 값들
	"key1" : "value"
  	"key2" : "value"
	"list1":[
    		"key3" : "value"
	        "key4" : "value"
		]  
      }, // nana id 2의 값들
	]

 

그래서 해결된 건가..?

 위의 방법을 사용해서 두 번에 걸쳐 쿼리 수를 줄였다. 28개 -> 25개 -> 21개. (쿼리 수는 intellij 터미널에서 hibernates를 검색한 기준이다.)

 

28개

더보기

Hibernate: 
    /* select
        member1,
        member1.language 
    from
        Member member1   
    left join
        member1.language 
    where
        member1.id = ?1 
        and member1.status = ?2 */ select
            m1_0.id,
            m1_0.birth_date,
            m1_0.created_at,
            m1_0.description,
            m1_0.email,
            m1_0.gender,
            m1_0.language_id,
            m1_0.level,
            m1_0.modified_at,
            m1_0.nickname,
            m1_0.image_file_id,
            m1_0.provider,
            m1_0.provider_id,
            m1_0.status,
            m1_0.type,
            l1_0.id,
            l1_0.created_at,
            l1_0.date_format,
            l1_0.locale,
            l1_0.modified_at 
        from
            member m1_0 
        left join
            language l1_0 
                on l1_0.id=m1_0.language_id 
        where
            (
                m1_0.status = 'ACTIVE'
            ) 
            and m1_0.id=? 
            and m1_0.status=?
Hibernate: 
    /* <criteria> */ select
        n1_0.id,
        n1_0.created_at,
        n1_0.modified_at,
        n1_0.version 
    from
        nana n1_0 
    where
        n1_0.id=?
Hibernate: 
    /* <criteria> */ select
        nt1_0.id,
        nt1_0.created_at,
        nt1_0.heading,
        nt1_0.image_file_id,
        nt1_0.language_id,
        nt1_0.modified_at,
        nt1_0.nana_id,
        nt1_0.notice,
        nt1_0.sub_heading 
    from
        nana_title nt1_0 
    where
        nt1_0.nana_id=? 
        and nt1_0.language_id=?
Hibernate: 
    /* <criteria> */ select
        nc1_0.id,
        nc1_0.content,
        nc1_0.created_at,
        nc1_0.image_file_id,
        nc1_0.modified_at,
        nc1_0.nana_title_id,
        nc1_0.number,
        nc1_0.sub_title,
        nc1_0.title 
    from
        nana_content nc1_0 
    where
        nc1_0.nana_title_id=? 
    order by
        nc1_0.number
Hibernate: 
    /* <criteria> */ select
        c1_0.id,
        c1_0.content,
        c1_0.created_at,
        c1_0.modified_at 
    from
        category c1_0 
    where
        c1_0.content=?
Hibernate: 
    /* <criteria> */ select
        f1_0.id,
        f1_0.category_id,
        f1_0.created_at,
        f1_0.member_id,
        f1_0.modified_at,
        f1_0.post_id 
    from
        favorite f1_0 
    where
        f1_0.member_id=? 
        and f1_0.category_id=? 
        and f1_0.post_id=?
Hibernate: 
    /* <criteria> */ select
        c1_0.id,
        c1_0.content,
        c1_0.created_at,
        c1_0.modified_at 
    from
        category c1_0 
    where
        c1_0.content=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?

25개

더보기

Hibernate: 
    /* select
        member1,
        member1.language 
    from
        Member member1   
    left join
        member1.language 
    where
        member1.id = ?1 
        and member1.status = ?2 */ select
            m1_0.id,
            m1_0.birth_date,
            m1_0.created_at,
            m1_0.description,
            m1_0.email,
            m1_0.gender,
            m1_0.language_id,
            m1_0.level,
            m1_0.modified_at,
            m1_0.nickname,
            m1_0.image_file_id,
            m1_0.provider,
            m1_0.provider_id,
            m1_0.status,
            m1_0.type,
            l1_0.id,
            l1_0.created_at,
            l1_0.date_format,
            l1_0.locale,
            l1_0.modified_at 
        from
            member m1_0 
        left join
            language l1_0 
                on l1_0.id=m1_0.language_id 
        where
            (
                m1_0.status = 'ACTIVE'
            ) 
            and m1_0.id=? 
            and m1_0.status=?
Hibernate: 
    /* select
        nana.id,
        nana.version,
        nanaTitle.id,
        nanaTitle.language.locale,
        nanaTitle.imageFile.originUrl,
        nanaTitle.imageFile.thumbnailUrl,
        nanaTitle.subHeading,
        nanaTitle.heading,
        nanaTitle.notice,
        nanaContent 
    from
        Nana nana   
    inner join
        NanaTitle nanaTitle 
            on nanaTitle.nana.id = ?1   
    inner join
        NanaContent nanaContent 
            on nanaContent.nanaTitle.id = nanaTitle.id   
    inner join
        ImageFile imageFile 
            on imageFile.id = nanaTitle.imageFile.id 
    where
        nanaTitle.language.locale = ?2 
    order by
        nanaContent.number asc */ select
            n1_0.id,
            n1_0.version,
            nt1_0.id,
            l1_0.locale,
            if2_0.origin_url,
            if2_0.thumbnail_url,
            nt1_0.sub_heading,
            nt1_0.heading,
            nt1_0.notice,
            nc1_0.id,
            nc1_0.content,
            nc1_0.created_at,
            nc1_0.image_file_id,
            nc1_0.modified_at,
            nc1_0.nana_title_id,
            nc1_0.number,
            nc1_0.sub_title,
            nc1_0.title 
        from
            nana n1_0 
        join
            (nana_title nt1_0 
        join
            image_file if2_0 
                on if2_0.id=nt1_0.image_file_id) 
            on nt1_0.nana_id=? 
        join
            nana_content nc1_0 
                on nc1_0.nana_title_id=nt1_0.id 
        join
            image_file if1_0 
                on if1_0.id=nt1_0.image_file_id 
        join
            language l1_0 
                on l1_0.id=nt1_0.language_id 
        where
            l1_0.locale=? 
        order by
            nc1_0.number
Hibernate: 
    /* <criteria> */ select
        c1_0.id,
        c1_0.content,
        c1_0.created_at,
        c1_0.modified_at 
    from
        category c1_0 
    where
        c1_0.content=?
Hibernate: 
    /* <criteria> */ select
        f1_0.id,
        f1_0.category_id,
        f1_0.created_at,
        f1_0.member_id,
        f1_0.modified_at,
        f1_0.post_id 
    from
        favorite f1_0 
    where
        f1_0.member_id=? 
        and f1_0.category_id=? 
        and f1_0.post_id=?
Hibernate: 
    /* <criteria> */ select
        c1_0.id,
        c1_0.content,
        c1_0.created_at,
        c1_0.modified_at 
    from
        category c1_0 
    where
        c1_0.content=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?
Hibernate: 
    /* <criteria> */ select
        h1_0.id,
        h1_0.category_id,
        h1_0.created_at,
        h1_0.keyword_id,
        h1_0.language_id,
        h1_0.modified_at,
        h1_0.post_id 
    from
        hashtag h1_0 
    where
        h1_0.language_id=? 
        and h1_0.category_id=? 
        and h1_0.post_id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        k1_0.id,
        k1_0.content,
        k1_0.created_at,
        k1_0.modified_at 
    from
        keyword k1_0 
    where
        k1_0.id=?
Hibernate: 
    select
        if1_0.id,
        if1_0.origin_url,
        if1_0.thumbnail_url 
    from
        image_file if1_0 
    where
        if1_0.id=?
Hibernate: 
    select
        il1_0.nana_content_id,
        il1_1.id,
        il1_1.created_at,
        il1_1.description,
        il1_1.info_type,
        il1_1.modified_at 
    from
        nana_info_type il1_0 
    join
        nana_additional_info il1_1 
            on il1_1.id=il1_0.nana_additional_info_id 
    where
        il1_0.nana_content_id=?

 

21개

더보기

Hibernate: 
    /* select
        member1,
        member1.language 
    from
        Member member1   
    left join
        member1.language 
    where
        member1.id = ?1 
        and member1.status = ?2 */ select
            m1_0.id,
            m1_0.birth_date,
            m1_0.created_at,
            m1_0.description,
            m1_0.email,
            m1_0.gender,
            m1_0.language_id,
            m1_0.level,
            m1_0.modified_at,
            m1_0.nickname,
            m1_0.image_file_id,
            m1_0.provider,
            m1_0.provider_id,
            m1_0.status,
            m1_0.type,
            l1_0.id,
            l1_0.created_at,
            l1_0.date_format,
            l1_0.locale,
            l1_0.modified_at 
        from
            member m1_0 
        left join
            language l1_0 
                on l1_0.id=m1_0.language_id 
        where
            (
                m1_0.status = 'ACTIVE'
            ) 
            and m1_0.id=? 
            and m1_0.status=?
Hibernate: 
    /* select
        nana.id,
        nana.version,
        nanaTitle.id,

 결과는.....

원래 상태 쿼리 28개 -> 859ms
시도 1 쿼리 21개 ->1044ms
시도2 쿼리 25개 -> 1101ms

 테스트 코드를 돌렸을 때 빠른 순으로 정리하자면 28개 -> 21개 -> 25개 이다... 테스트는 돌릴 때마다 속도가 달라지지만 빠른 순서는 바뀌지 않았다.

 

(모든 코드를 보고 싶다면 아래의 링크로...)

https://abalone-athlete-adb.notion.site/QueryDsl-019fd12aee5c4636b0c285d9a8879eec?pvs=4)

 

결론

 작지만 쿼리의 수가 줄어드는 것을 보고 두근두근 했지만 테스트를 돌려보고 조금은 절망적이었다 ㅋㅋㅋㅋㅋㅋ 하지만 깨달은 큰 결론 쿼리의 수가 줄어들면 무조건 속도가 빨라진다? 가 절대 아니다. 찾아보니 쿼리 속도 개선에는 쿼리의 수가 중요한 것이 아니라 상황에 따라 여러 규칙을 지켜야 했다.(좌변은 연산하지 않기, OR 대신 UNIION 사용 등등,,,) 그래서 일단 원상태로(JPA 메서드 사용) 돌려놓았다. 전에는 "쿼리 왜 알아야 하지 jpa가 다해주는데", "DML? 몰라도 될 것 같은데" 싶었지만 정말 어리석고 가벼운 생각이었다 허허.... 쿼리 성능 개선에 관심이 생겼고 SQLD 자격증에 갑자기 관심이 생겼다. 과연 이후의 결과는????? (sqld 자격증 접수해야겠다.)

728x90
반응형
저작자표시 (새창열림)

'My project > Nanaland in Jeju' 카테고리의 다른 글

프로젝트 진행 시 엑셀에 작성한 데이터, DB에 저장하는 방법  (0) 2024.10.17
스프링 검색어 자동완성 비동기 처리 (Feat. 1만번의 부하테스트 결론은 Over Engineering 이었다고 한다..)  (5) 2024.08.29
검색어 자동완성 구현하기 with Redis (Feat. Elasticsearch)  (3) 2024.08.01
Stream API 사용 중 .toList()에서 UnsupportedOperationException 발생한 썰  (1) 2024.07.26
맥에서 MySql, MaraiDB 두개 다 사용하기 (Feat. Docker 이래서 쓰는구나, 맥 mariaDB 설치하기)  (2) 2024.03.27

    티스토리툴바