데이터베이스/mysql

Mysql 묵시적 형변환

위들 wedul 2018. 10. 3. 23:47
반응형

묵시적 형변환
조건절의 데이터 타입이 다를 때 우선순위가 높은 타입으로 형이 내부적으로 변환 되는 것. 
정수 > 문자열 순이며 만약 정수와 문자열이 비교가 되는 경우에는 둘중에 우선순위가 낮은 것이 변경된다. 

우리는 이렇게 자동으로 형변환 해주는 경우에 익숙해져 있다. 자바에서도 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(64not 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에서 데이터를 #{}형태로 넣어서 사용할 때 문제 없이 실행되기 때문에 잘 몰라서 문제소지를 일으킬 수 있다.

항상 조심하자.


728x90
반응형
1 2 3 4 5 6 7 ··· 13