Index를 타지않는 쿼리

1. 인덱스 컬럼을 변형하는 경우

홍찬기
3 min readApr 21, 2022

SQL문을 사용할때 인덱스 컬럼을 변형을 시키면 데이터베이스가 인덱스를 사용하지 않는다.

SELECT * FROM users WHERE LOWER('first_name') = 'hong'SELECT * FROM table WHERE ages+10 = 30 -> 인덱스 사용불가SELECT * FROM table WHERE ages = 20 + 10 -> 인덱스 사용가능

2. NULL 조건의 사용

NULL조건을 사용하면 Table Full Scan이 발생한다.

SELECT * FROM users WHERE ages IS NULL -> 인덱스 사용불가SELECT * FROM users WHERE ages IS NOT NULL -> 인덱스 사용불가SELECT * FROM users WHERE ages > 0 -> 인덱스 사용가능SELECT * FROM users WHERE ages > '' -> 인덱스 사용가능

3. 부정형의 사용

NOT일 경우 무조건 인덱스를 안타는 것이 아니라 일반적으로 NOT에 사용된 값이 아닌 데이터 비율이 높은 경우가 많기 때문에 인덱스를 타지 않는다.

SELECT * FROM users WHERE ages != 31 -> 인덱스 사용불가SELECT * FROm users WHERE ages < 31 AND ages > 31 -> 인덱스 사용가능

4. LIKE문을 사용할때 전체 범위를 설정할시

LIKE문을 사용할때 항상 인덱스를 안타는것이 아니라 ‘%’가 앞에 붙을때 인덱스를 타지 않는다.

SELECT * FROM users WHERE first_name LIKE '%hong%' -> 인덱스 사용불가SELECT * FROM users WHERE first_name LIKE 'hong%' -> 인덱스 사용가능

5. IN 연산자를 사용할경우

IN의 경우 항상 인덱스를 타지 않는것이 아니라 IN에 포함된 데이터들의 비율이 매우 높다면 Table Full Scan을 하는 것이 낫다고 데이터베이스가 판단하면 인덱스를 타지 않는다.
Mysql에서 5.7버전 이상부터는 range_optimizer_max_mem_size 값이 0으로 되어있으면 인덱스가 타지고 값이 있으면 해당 값보다 메모리를 더 사용하면 Table Full Scan 또는 이외의 인덱스가 타진다.

SELECT * FROM users WHERE ages IN (20, 21, 22) 

6. 복합인덱스에서 첫인덱스가 첫조건으로 적용하지 않았을경우

복합인덱스에서 인덱스의 순서가 name , age 인경우 name -> age의 순서로 조건을 걸어야 인덱스를 탈 수 있다.

SELECT * FROM users WHERE name = 'hong' AND age = 30 -> 인덱스 사용가능SELECT * FROM users WHERE age = 30 AND name = 'hong' -> 인덱스 사용불가

7. 인덱스 컬럼의 내부적인 데이터 변환

문자값 데이터타입을 갖는 컬럼에 ‘값’ → 값 을 하지 말고 정확한 데이터 타입을 넣어야 인덱스를 탈 수 있다.

SELECT * FROM users WHERE age = '30' -> 인덱스 사용불가SELECT * FROM users where age = to_number('30') -> 인덱스 사용가능

--

--