ABOUT ME

-

오늘 방문자
-
어제 방문자
-
전체
-
  • [QueryDSL] 데이터 존재 유무 체크로직 성능 테스트
    JPA 2021. 3. 25. 00:23

     

    요약 :  데이터 존재 유무 체크 로직 작성시, fetchCount()가 아닌, fetchFirst()를 쓰자!

     

    주의사항 : fetchFirst() 수행시, 데이터가 없으면 0을 반환할 줄 알았는대, 0이 아닌 NULL을 반환했다. NULL체크 로직 필수!

     

     

     

     

    테스트 시나리오 :  H2DB를 사용했고, 약10만건의 데이터를 insert후, 특정 데이터가 존재하는지 확인!

     

    결과 : fetchCount  소요시간 : 약 38초,  fetchFirst() 소요시간 : 약 31초.

     

    실행쿼리를 보면 fetchCount()는 count() 쿼리를 사용하였고, fetchFirst는 limit 1을 사용하였다.

    전체컬럼을 스캔하는 count()보다야 limit 1이 훨씬 빠르니, 이러한 결과가 나왔다.

     

      /**
         * 데이터 존재 유무, fetchCount() 소요시간 테스트
         * */
        @Test
        public void exist성능_테스트_fetchCount(){
            for(int i=0 ; i<=100000;i++){
                Member member = new Member(String.valueOf(i), i, null);
                em.persist(member);
            }
    
            long startTime = System.currentTimeMillis(); // 시간측정 START
    
            boolean integer = queryFactory
                    .selectOne()
                    .from(member)
                    .where(member.username.eq("50000"))
                    .fetchCount()>0;
    
            long endTime = System.currentTimeMillis(); // 시간측정 END
    
            long diffTime = (endTime - startTime)/1000;
    
            System.out.println("소요시간 = " + diffTime);
        }
     select
            count(member0_.id) as col_0_0_ 
        from
            member member0_ 
        where
            member0_.username=?

     

     

     

    fetchFirst() 

        /**
         * 데이터 존재 유무, fetchFirst() 소요시간 테스트
         */
        @Test
        public void exist성능_테스트_fetchFirst(){
            for(int i=0 ; i<=100000;i++){
                Member member = new Member(String.valueOf(i), i, null);
                em.persist(member);
            }
    
            long startTime = System.currentTimeMillis(); // 시간측정 START
    
            Integer integer = queryFactory
                    .selectOne()
                    .from(member)
                    .where(member.username.eq("50000"))
                    .fetchFirst();
    
            // return integer != null;
    
            long endTime = System.currentTimeMillis(); // 시간측정 END
    
            long diffTime = (endTime - startTime)/1000;
    
            System.out.println("소요시간 = " + diffTime);
        }
     select
            1 as col_0_0_ 
        from
            member member0_ 
        where
            member0_.username=? limit ?

     

    'JPA' 카테고리의 다른 글

    지연로딩, 즉시로딩  (0) 2021.08.22

    댓글

Designed by Tistory.