RDB를 운영하다 보면 범위검색은 심심치 않게 발생한다
이번 글에선 범위 검색 중 흔히 사용하는 조건절의 BETWEEN과 LIKE의 차이 및 효율에 대해 다뤄보고자 한다
먼저 이해를 돕기 위해 송금 집계 테이블이 있다고 가정하자
송금 집계 테이블엔 송금 날짜, 송금 타입 컬럼이 있다
송금 집계 테이블의 송금 날짜 레코드는 202312 ~ 202501까지 존재한다
송금 집계 테이블의 송금 타입 레코드는 A와 B가 있으며, A = 90만 건, B = 10만 건 (9:1) 비율로 존재한다
송금 집계 테이블엔 (송금 날짜, 송금 타입) 인덱스가 존재한다 (편하게 idx1 로 부르자)
위 정보를 바탕으로 idx1를 시각화하면 다음과 같다
우린 2024년에 B 타입으로 송금한 레코드 정보를 찾기 위해 다음과 같은 조건절을 활용할 수 있다
-- BETWEEN --
WHERE 송금_날짜 BETWEEN '202401' AND '202412'
AND 송금_타입 = 'B'
-- LIKE --
WHERE 송금_날짜 LIKE '2024%'
AND 송금_타입 = 'B'
다음은 각각의 조건절을 시각화하여 어떻게 동작하는지 알아보자
위 그림을 보고 어떤 차이인지 단번에 알아차렸다면, 이 글을 다 본 것이나 다름없다 🤩
정확한 차이는 바로 인덱스 스캔 시작 지점과 인덱스 스캔 종료 지점이다.
BETWEEN의 경우, 202401과 B 로 시작하는 레코드를 스캔 시작 지점으로 잡고, 이후 필터를 수행한다
하지만 LIKE의 경우 202401 맨 처음 레코드부터 스캔을 시작한 것으로 보이는데, 이유가 무엇일까?
바로 202400 레코드의 존재 가능성 때문이다
사람은 202400이 없는 것을 알고 있지만, DB는 그것을 알지 못하기에 인덱스 스캔 시작 지점을 위와 같이 잡을 수 밖에 없는 것이다
그럼 반대의 경우는 어떨까?
송금 집계 테이블의 송금 타입 레코드 비율을 A = 10만건, B = 90만 건(1:9) 비율로 존재한다고 가정해 보자
검색하고자 하는 조건은 다음과 같다
-- BETWEEN --
WHERE 송금_날짜 BETWEEN '202401' AND '202412'
AND 송금_타입 = 'A'
-- LIKE --
WHERE 송금_날짜 LIKE '2024%'
AND 송금_타입 = 'A'
위 실행계획을 보면 이제 어떤 차이가 있는지 알겠는가?
BETWEEN의 경우 202412의 A 레코드가 스캔 종료 지점임을 알고 있지만
LIKE의 경우 202413의 가능성 때문에 202501의 첫 번째 리프 블록을 보고 나서야 스캔을 멈춘다
사소한 차이로 보이지만, 분명한 차이가 있는 것이다
결론 : LIKE 대신 BETWEEN 써서 손해 볼 건 없다 🤗
'개발 > Database' 카테고리의 다른 글
[Join Series] 1. NL Join (Nested Loop) (0) | 2025.03.22 |
---|---|
[Join Series] 매번 눈에 밟히는 그 조인 시리즈 (0) | 2025.03.18 |
[Spring/Postgres] SKIP Lock 사용하여 동시성 이슈 해결하기 (0) | 2025.03.01 |
[Spring/Postgres] Exclusive Lock 제대로 사용하기 (동시성 문제) (0) | 2025.02.22 |
[macOS/Intellij/Oracle] ventura 13.0 업데이트 이후 로케일을 인식할 수 없습니다.(SQL Error: 17176) - 해결 (0) | 2022.11.08 |
댓글