countBy 보단 existsBy

countBy 보단 existsBy

SQL Insert시 중복검사, countBy 보단 existsBy

 

오늘 아주 잘못된 개발 방식 하나를 고쳤다.

나는 JPA로 Insert 작업을 할 때 중복검사를 해 값이 없을 때만 insert 해야 하는 경우에

countBy~를 사용해 count > 1이라는 조건으로 개발을 하고 있었다.

 

Long countByGuid(String guid);
boolean existsByGuid(String guid);

 

JPA문서들을 보다 보니

그게 참 바보 같은 짓이었다는 걸 깨닫게 됐다.

머리를 망치로 얻어맞은 듯하여 바로 실험을 해보니,

 

SELECT
        FEEDBOARD0_.FEED_BOARD_ID AS COL_0_0_ 
    FROM
        FEED_BOARD FEEDBOARD0_ 
    WHERE
        FEEDBOARD0_.TITLE='안녕하세요' LIMIT 1

 

existsBy~를 사용하면 select count(*)가 아닌, select ~ limit 1이라는 쿼리가 발생한다.

 

즉, countBy와 비슷하지만 순회 검색 중 중복되는 게 단 하나라도 있는 경우

그 즉시 쿼리를 종료하는 것이므로 모든 개수를 세는 count보다 압도적으로 좋은 성능을 보인다.

 

아주 간단한 실험 결과 데이터가 얼마 없음에도 불구하고 2배 이상의 성능 차이를 보여줬다.

실제 서비스의 운영환경에서는 정말로 유의미한 성능차이가 발생할거라 판단된다.

 

이 외에도 DB의 유니크 제약조건@SQLInsert 같은 JPA 애노테이션을 활용하는 방법 등이 있었으나,

나는 기본키 생성 전략이 IDENTITY이기 때문에 뜻대로 되질 않았다.

다만 SEQUENCE로 할 경우 충분히 활용 가치가 있다는 생각이 들기에 기록해놓고 잘 외워둬야 하겠다.

 

@SQLInsert(sql="INSERT IGNORE INTO EntityClass(id,name) VALUES(?,?)")
class EntityClass{
   ...
}

 


© 2022. All rights reserved.