본문 바로가기
DataBase

[MySQL] BETWEEN 연산자를 활용한 쿼리 최적화

by bkuk 2023. 4. 11.

BETWEEN 연산자

BETWEEN 연산자는 "크거나 같다"와 "작거나 같다"라는 두 개의 연산자를 하나로 합친 연산자다. 다른 비교 조건과 결합해 하나의 인덱스를 사용할 때 주의해야 할 점이 있다. 아래 동등 비교 연산자와 BETWEEN 연산자를 이용해 부서 번호와 사원 번호로 dept_emp 테이블을 조회하는 다음 쿼리를 한번 생각해보자.

 

SELECT * FROM dept_emp 
	WHERE dept_no = 'd003' AND emp_no = 100001;
    
SELECT * FROM dept_emp
	WHERE dept_no BETWEEN 'd003' AND 'd005' AND emp_no = 100001;

 

dept_emp 테이블에는 (dept_no, emp_no) 컬럼으로 구성된 프라이머리 키가 존재한다. 그래서 첫 번째 쿼리는 dept_no와 emp_no 조건 모두 인덱스를 이용해 범위를 줄여주는 방법으로 사용할 수있다. 

 

하지만 두 번째 쿼리에서 사용할 BETWEEN은 크다 또는 작다 연산자와 같이 범위를 읽어야 하는 연산자라서 dept_no가 'd003' 보다 크거나 같고 'd005'보다 작거나 같은 모든 인덱스의 범위를 검색해야만 한다. 결국 BETWEEN이 사용된 두 번째 쿼리에서 emp_no=10001 조건은 비교 범위를 줄이는 역할을 하지 못한다.

 

BETWEEN 연산자와 IN 연산자의 차이

BETWEEN과 IN을 동일한 비교 연산자로 생각하는 사람도 있는데, 사실 BETWEEN은 크다와 작다 비교를 하나로 묶어 둔 것에 가깝다. 그리고 IN 연산자의 처리 방법은 동등 비교(=) 연산자와 비슷하다.

IN 연산자는 여러 개의 동등 비교(=)를 하나로 묶은 것과 같은 연산자라서 IN과 동등 비교 연산자는 같은 형태로 인덱스를 사용한다.

BETWEEN 쿼리를 아래와 같은 형태로 개선하면 인덱스를 사요하여 효율적인 쿼리를 만들 수 있다.

// 1. 개선 전
SELECT * FROM dept_emp
	WHERE dept_no BETWEEN 'd003' AND 'd005' AND emp_no = 100001;
    
// 2. 개선 후
SELECT * FROM dept_emp
	WHERE dept_no IN ('d003', 'd004', 'd005') AND emp_no = 100001;

 

 

BETWEEN이 선형으로 인덱스를 검색해야 하는 것과는 달리 IN은 동등(Equal) 비교를 여러 번 수행하는 것과 같은 효과가 있기 때문에 dept_emp 테이블의 인덱스(dept_no, emp_no)를 최적으로 사용할 수 있는 것이다.

 

 

참고: Real MySQL 8.0

댓글