MSSQL에서 DataType Issue 성능개선 (VARCHAR type의 NVARCHAR type으로의 형변환 문제)
성능테스트를 할때 이슈가 발생을 하였다. 성능이 생각만큼 나오지 않아서 원인을 찾다가 한가지 흥미로운 사실을 발견했다. MSSQL은 DataType에 따라서 우선순위가 존재하는데 NVARCHAR가 VARCHAR보다 더 높은 우선순위를 가지고 있다. 내가 Query의 Binding할 문자열에 대해 DataType을 지정하지 않고 그냥 값을 넘기면 MSSQL의 내부 규칙에 의해 NVARCHAR type으로 값이 넘어가게 된다.
SELECT * FROM TB_EMP WHERE EMP_NAME LIKE 'Volibear';
이렇게 넘긴다면 넘긴 Volibear라는 값은 NVARCHAR로 넘어간다는것이다.
CREATE TABLE TB_EMP ( EMP_ID varchar(100), EMP_NAME varchar(100) );
NVARCHAR로 넘긴 값이 위와 같이 VARCHAR로 정의한 컬럼에 매핑이 되어야 하는데 Type이 맞아야 비교를 할 수 있기에 EMP_NAME 컬럼의 값을 DataType 우선순위에 의해 NVARCHAR type으로 형변환을 하고 비교를 한다. 따라서 VARCHAR->NVARCHAR로 형변환이 되게 되고 기존에 VARCHAR일때 설정되었던 index는 모두 사라진다. 그래서 느려지는 현상이 발생하는것이다.
해결책.
첫번째 방법으로는 컬럼에 Type Casting을 해주면 된다.
SELECT * FROM TB_EMP WHERE CAST(EMP_NAME AS VARCHAR) LIKE 'Volibear';
CAST로 해줘도 되고 CONVERT로 해줘도 된다. string parameter는 아무것도 설정하지 않으면 기본으로 NVARCHAR로 지정되는 것을 막고자 강제로 Type을 지정해 주는 것이다. 고쳐야할 코드가 많은 경우는 사용하기 힘들다.
두번째 방법으로는 sendStringParametersAsUnicode=false 를 사용하는 방법이다.
jdbc:sqlserver://ip:port;sendStringParametersAsUnicode=false
datasource url 설정부에 위와 같은 옵션을 추가시켜준다. 이 옵션의 역할은 위에서 언급한대로 MSSQL은 String Parameter에 대해서 기본적으로 NVARCHAR로 매핑을 시켜주는데 VARCHAR로 매핑해주고 싶은 경우에 사용한다.
끝!