JOIN, LEFT JOIN (feat. query tuning)

hyozkim·2020년 3월 10일
0

JOIN

JOIN을 사용한 쿼리와 아닌 쿼리를 비교하면 쿼리를 봤을때 보기도 좋고 이해도 빨리 된다.
JOIN을 사용하면 쿼리를 짜면서 머리속에 테이블이 더 잘 그려지는 듯하다.

select를 두번 사용한 쿼리
-- as-is
select 
	count(*) as count, a.category_id as id, a.category_name as name
 from 
	display_info d, 
	( 
		select 
			c.id as category_id, c.name as category_name, p.id as product_id 
		from category c JOIN product p ON c.id = p.category_id 
	) a 
 WHERE d.product_id = a.product_id 
 group by a.category_id ;

JOIN을 사용한 쿼리

-- to-be
select 
	count(*) as count, c.id as category_id, c.name as name
from 
	category c JOIN product p ON c.id = p.category_id 
				JOIN display_info d ON d.product_id = p.id
group by c.id;

LEFT JOIN

LEFT JOIN 혹은 LEFT OUTER JOIN이라고 명명한다.
개발할 때, OUTER JOIN을 사용하여 개발하면 좀 더 간단하게 개발할 수 있다.

// as-is
        List<Comment> comments = commentRepository.findById(displayInfoId);
        List<Comment> commentImages = commentImageRepository.findById(displayInfoId);

        for( Comment comment : comments ) {
            for( CommentImage commentImage :commentImages  ) {
                if( comment.getCommentId().value() == commentImage.getReservationUserCommentId() ) {
                    comment.setCommentImage(findCommentImages(fileId));
                }
            }
        }

이미지가 있는 댓글, 이미지가 없는 댓글을 가져오기 위해 무식하게 for문을 2개 써서 개발했었다. Comment 테이블, CommentImage 테이블 모두 commentId을 가지니까 이를 비교하여 일치하는 경우, 이미지를 세팅한다. ( 없으면 null ) 매우 비효율적이다.

// to-be
List<Comment> comments = commentRepository.findById(displayInfoId);
        for( Comment comment : comments ) {
            Id<FileInfo,Long> fileId = comment.getFileId();
            if( fileId.value() != 0 ) {
                findCommentImages(fileId).map(commentImages -> {
                    comment.setCommentImage(commentImages);
                    return comment;
                });
            }
        }

LEFT JOIN을 사용한 쿼리 튜닝만으로 for문 1개를 줄일 수 있었다.

LEFT JOIN을 사용한 쿼리와 결과

select 
	c.product_id productId, c.comment as comment, c.id as commentId, c.create_date as createDate, c.modify_date as modifyDate, r.reservation_date as reservationDate, r.reservation_email as reservationEmail, r.id as reservationInfoId, r.reservation_name as reservationName, r.reservation_tel as reservationTelephone, c.score as score,
        ifnull(i.file_id, false) as imageExist
from 
	reservation_info r JOIN reservation_user_comment c ON r.id = c.reservation_info_id LEFT JOIN reservation_user_comment_image i ON c.id = i.reservation_user_comment_id 
where 
	r.display_info_id = 1;  

imageExist 컬럼을 추가한 쿼리 튜닝을 통해 사용할 수 있다!
물론! 데이터 상황에 따라 고려해야 한다!!

profile
차근차근 develog

0개의 댓글