database

mysql index를 타지않는 경우

MIN우 2024. 3. 17. 13:21
728x90

인덱스를 타지 않는 경우

 

1. 인덱스  컬럼의 변형

select * from table where LOWER(name)  ='word';
select * from table where idx - 1 = 5;


이 처럼 인덱스에 변형을 가하게 되면, DBMS가 인덱스를 이용하지 않는다.

 

 

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

select * from table where age = '30'

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

 


3. NOT 또는 IN 연산자 사용


NOT일 경우에도 인덱스를 타긴 타지만, 일반적으로, NOT에 사용된 값이 아닌 데이터의 비율이 높은 경우가 많기 때문에 인덱스를 타지 않는 경우가 많다.
마찬가지로 IN일 경우에도, IN에 포함된 데이터들의 비율이 매우 높다면 FULL SCAN을 하는 것이 낫다고 DBMS가 판단하면 인덱스를 타지 않는다.

Mysql에서 5.7버전 이상부터는 range_optimizer_max_mem_size 값이 0으로 되어있으면 인덱스를 타고 값이 있을 경우, 해당 값보다 메모리를 더 사용하면 Table Full Scan 또는 이외의 인덱스가 타진다.

 


4. 와일드 카드 LIKE문장에서 범위를 전체를 지정할 경우

select * from table where name like '%word';


문자열로 이루어진 값을 인덱스로 잡았을 때, %가 앞쪽에 사용되면 정렬 순서를 사용할 수 없으므로 테이블 FULL SCAN이 이루어진다.

select * from table where name like 'word%';


이런 경우는 문자열 정렬 순서를 그대로 이용할 수 있기 때문에 인덱스를 탈 수 있다.

 


5. 복합 컬럼 index에서 순서가 잘못되어 index 가 적용 되지 못하는경우

결합 인덱스 = 칼럼1,칼럼2
select * from table where 칼럼2

조건절에서 컬럼1을 조건에서 사용하지 않는다면, 그 인덱스는 사용되지 않는 경우가 대부분이다.  그렇기에 많은 쿼리에서 공통적으로 사용된 조건절의 컬럼을 인덱스 선행 칼럼에 주로 사용한다.

 

 

6. OR 조건 일 경우 

select * from table where name = 'word' or idx = 5


name과 idx가 둘다 인덱스가 걸려있는 경우라해도, DBMS가 최적의 OR 조건을 뽑기 힘들어, FULL SCAN 하는 경우가 많다.

 

 

7. Optimizer 의 선택

select * from table where name ='word' and id ='elky';


인덱스가 name 과  id로 2개가 있을 경우 id나 name 인덱스 중 하나가 선택될 수도 있고, 둘 다 선택될 수도 있다.
어떤 방식으로 선택하는냐가 속도에 중요할 수도 있다. 즉 실행 계획을 추적해서 원하는 결과가 나오도록 관리가 필요하다.

728x90