반응형
묵시적 형변환
조건절의 데이터 타입이 다를 때 우선순위가 높은 타입으로 형이 내부적으로 변환 되는 것.
정수 > 문자열 순이며 만약 정수와 문자열이 비교가 되는 경우에는 둘중에 우선순위가 낮은 것이 변경된다.
우리는 이렇게 자동으로 형변환 해주는 경우에 익숙해져 있다. 자바에서도 Integer와 int 두 개의 변수의 값을 묵시적으로 형변환 시켜주지만 이는 이펙티브 자바 책에서도 볼 수 있지만 성능저하의 원인이 된다고 한다.
Mysql도 예외가 아닌 것 같다.
예를 들어 보자 아래와 같은 테이블을 생성 후 데이터를 삽입한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # 테이블 생성 create table chagne_data ( id int unsigned not null auto_increment, sub_id int unsigned not null, val varchar(64) not null, date_d datetime not null, primary key(id) ); # 랜덤 데이터 삽 insert INTO chagne_data ( sub_id, val, date_d ) values ( crc32(rand()), crc32(rand()) * 12345, date_add(now(), interval - crc32(rand()) / 5 second) ); INSERT INTO test.chagne_data(sub_id, val, date_d) SELECT sub_id, val, date_d FROM test.chagne_data; | cs |
인덱스를 생성하고
정수형 컬럼에 문자열 조건을 주어서 실행계획을 확인해보자.
1 2 3 4 5 | # 인덱스 생성 CREATE INDEX int_index ON test.chagne_data(sub_id); # 정수형에 문자열형 조건으로 추가 (정수가 더 우선순위가 높으므로 문제 없음) SELECT * FROM test.chagne_data where sub_id = '3689107608'; | cs |
별 문제 없다. 왜냐면 정수형 데이터가 우선순위가 더 높기 때문에 우측의 문자열 데이터가 변경되었기 때문에 인덱스를 정상적으로 사용했기 때문이다.
그렇다면 문자열 컬럼을 정수형 데이터로 조건을 주어서 데이터를 추출한다면 어떨까?
우선 정상적인 경우의 실행계획을 살펴보자.
1 2 3 4 5 | # 인덱스 생성 CREATE INDEX int_index ON test.chagne_data(val); # 문자열에 문자열로 조건을 주고 실행계획 확인 SELECT * FROM test.chagne_data WHERE val = '10227816402120'; | cs |
이번에는 문자열 컬럼에 정수 데이터를 넣고 조회해보자.
1 2 | # 문자열에 정수형 조건 추가 (묵시적 형변환 발생) SELECT * FROM test.chagne_data WHERE val = 10227816402120; | cs |
인덱스 사용을 못하고 문제가 되는 것을 확인 할 수 있다.
특히 이런 문제가 발생하는 대표적인 부분이 mybatis에서 데이터를 #{}형태로 넣어서 사용할 때 문제 없이 실행되기 때문에 잘 몰라서 문제소지를 일으킬 수 있다.
항상 조심하자.
반응형
'데이터베이스 > mysql' 카테고리의 다른 글
Mysql 인덱스 사용법 및 실행 계획 정리 (0) | 2020.06.10 |
---|---|
[공유] mysql/mariadb utf8mb4 언어셋 설명 (0) | 2018.11.06 |
Mysql 실행계획 설명 (0) | 2018.10.03 |
Mysql Exists와 IN절 설명과 차이점 (0) | 2018.10.03 |
Mysql의 서버엔진과 스토리지 엔진 (0) | 2018.08.10 |