행궁동 데이터 엔지니어

반응형

특정 조건의 데이터가 존재하는지 확인하기 위해 EXISTS 쿼리를 사용할 때가 있습니다.

EXISTS는 조건과 맞는 row 찾으면 이후 rows들은 탐색하지 않기 때문에 빠른 조회가 가능한 장점이 있습니다.

(최소 1개에서 ~ 최대 전체 N개 Rows까지 탐색하게 됩니다.)

EXISTS 문법

Exists는 EXISTS(서브쿼리) 형태로 Where절이나 Select절에서 사용합니다.

  • 결과 값은 존재하는 행이 있을 경우 True(1)
  • 존재하는 값이 없을 경우 False(0)을 반환 합니다.
-- 1. Where 절에서 사용하는 예시 (중첩 서브쿼리, 서브쿼리)
-- * Where 절에서 사용하는 서브쿼리를 중첩 서브쿼리 또는 그냥 서브쿼리라고 합니다.
SELECT
    select_column
FROM
    products
WHERE
    EXISTS(subquery);

-- 2. Select 절에서 사용하는 예시 (스칼라 서브쿼리)
-- * Select 절에서 사용하는 서브쿼리를 스칼라 서브쿼리 라고 합니다.
SELECT EXISTS(subquery);

-- 참고: 모브님 개발블로그, https://mauvpark.github.io/docs/Sql/MySQL/2021-12-13-a-mysql19.html

아래의 예시코드를 보면 이해가 수월하실 겁니다.

예시 코드

  • 환경
    • MySQL 5.7.39
  • 조건
    • PRODUCTS 테이블 (약 3천만 Rows)
    • created_at 컬럼은 Indexing 되어있음
    • 2022년 1분기 (1월 ~ 3월)에 등록된 상품 중 상품 가격이5,000만원이 넘는 이상한 상품이 있었는지 확인하기

CASE 1: Count로 확인

쿼리: 2022년 1 ~ 3월 데이터에서 상품 가격(price)이 5,000만원이 넘는 경우가 1개 이상인지 조회 (전체 Count)

select
    count(1) >= 1 as check_product
from
    products
where
      created_at between '2022-01-01' and '2022-04-01'
  and price > 50000000;

실행 시간: 6s 118ms

6s 118ms

CASE 2: Exists로 확인

쿼리: Select 절에 Exists를 사용하여 2022년 1 ~ 3월 등록 상품 중 5,000만원이 넘는 경우를 만나면 바로 True(1)을 리턴하고 종료

select
    exists(select *
           from
               products
           where
                 created_at between '2022-01-01' and '2022-04-01'
             and price > 50000000) as check_product;

실행 시간: 8ms

중간에 5,000만원이 넘는 상품을 찾아 바로 종료되는 경우8ms가 걸렸습니다. CASE 1(6s 118ms)과 비교할 수 없이 빠릅니다.

8ms

CASE 3: Limit를 이용해 Exists처럼 확인

Limit 1 조건을 통해 1개 행이라도 찾으면 서브쿼리가 결과를 반환하도록 설정

* 아래와 같이 FROM절에서 사용하는 서브쿼리를 인라인 뷰(Inline View)라고 합니다.

select
    count(1) >= 1 as check_product
from
    (select
         'product' as check_exists
     from
         products
     where
           created_at between '2022-01-01' and '2022-04-01'
       and price > 50000000
     limit 1) as strange_product;

실행 시간: 9ms

Limit 1을 사용하여 조건에 맞는 1개 행만 만나면 서브쿼리 결과를 리턴하도록 했기에 Exists와 거의 같은 시간(9ms)이 나왔습니다.

9ms

기타 궁금하신 사항은 편하게 댓글 남겨주세요.

감사합니다.

1. 향로님 블로그, "JPA exists 쿼리 성능 개선", https://jojoldu.tistory.com/516
2. 모브님 블로그, "MySQL 19. EXISTS", https://mauvpark.github.io/docs/Sql/MySQL/2021-12-13-a-mysql19.html
3. MySQL Documnet, https://dev.mysql.com/doc/refman/8.0/en/exists-and-not-exists-subqueries.html

반응형

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band