몇 개 테이블을 조인하고 union all 하여 데이터를 가져와 화면에 표시하는 작업을 진행하고 있었다.
DBMS에서는 쿼리 실행 실행시간이 2초인데 실제 화면 상에서는 50초 이상 기다려야 결과값이 나왔다.
로그를 추적해보니 백엔드에서 넘어가고 나서 DB에서 결과 값이 나오는데 시간이 걸렸다.
쿼리 상 파라미터로 넘어가는데 2개가 있는데 둘 다 문자열이었고 구글링을 통해 아래와 같은 이슈 찾았고 해결했다.
# 결론
SQL Server JDBC Driver는 String 파라미터를 NVARCHAR로 전환되어 매핑된다.
테이블 내 VARCHAR로 되어 있고 인덱스가 설정되어 있을 경우 NVARCHAR로 전환되어 인덱스가 작동되지 않는다.
VARCHAR로 매핑되게 변경하려면 JDBC URL에 sendStringParametersAsUnicode=false 를 추가해야 한다.
아니면 쿼리문에 CAST 함수를 사용하여 VARCHAR로 형변환을 해야 한다. (수정해야 할 쿼리가 복잡한 경우 비추)
# 문제점
MS-SQL JDBC Driver의 String 파라미터는 설정되거나 직접 지정하지 않을 경우 문자열의 경우 NVARCHAR로 지정되어 매핑됨
(DataType에 따라 우선순위가 존재하는데 NVARCHAR가 VARCHAR보다 더 높은 우선 순위를 가짐)
# 해결 방법
1. 쿼리문에 CAST 함수를 사용하여 형변환
SELECT *
FROM TB
WHERE
VARCHAR 컬럼 = CAST('String 파라미터' AS VARCHAR)
2. SQL Server JDBC Driver URL 설정 추가
jdbc:sqlserver://ip:port;sendStringParametersAsUnicode=false
datasource url 설정에 위와 같이 옵션을 추가한다.
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost:1433;database=데이터베이스;sendStringParametersAsUnicode=false
* 옵션을 보면 String 파라미터를 유니코드로 넘기는 설정이 false, 즉 ASCII로 넘긴다는 설정임
(NVARCHAR, NCHAR가 아니라 VARCHAR, CHAR로 넘김)
※ VARCHAR 데이터 형식
가변 문자열, ASCII 데이터 저장 시 사용
영문, 숫자는 1byte로 저장
한글, 한자는 2byte로 저장
최대 8000byte까지
※ NVARCHAR 데이터 형식
가변 문자열, UNICODE 문자 저장 시 사용
다국어 지원 시 NVARCHAR를 사용하기
어떤 문자든 2byte로 저장
최대 4000byte까지