<피드백 언제나 환영합니다! 댓글 감사합니다>
쿼리에 인덱싱을 걸어서 사용하였음에도 불구하고 DB 속도가 너무 늦게 나오네요 분명 DB tool 에서 조회시에는 느리지 않았는데..
그래서 검색 해본결과 MS_SQL 은 성능을 추적 할 수 있는 도구가 있어서 실행 해보았습니다.
Profileing 하는 법은 아래 두 블로그를 보고 확인 하였습니다.
확인 해보니 varchar 로 지정 하던 것이 nvarchar로 나가게 되면서 인덱싱 또한 깨지게 됩니다.
관련 검색중 우아한 형제 블로그
에서 저와 비슷한 증상이 있어 적용해 보니 해결이 되었습니다.
![](https://techblog.woowahan.com/wp-content/uploads/2021/06/screenshot.jpg)
그래서 간단히 적용 하는 방법과 왜 그런 문제가 있는지 간단하게 알아 보겠습니다.
문제점
SQL Server JDBC Driver 의 String 파라미터들은 nvarchar 로 매핑합니다 심지어 PreparedStatement.set 호출시 varcar 로 매핑하여도 nvarchar로 매핑 되는 문제
MS 공식 문서에 따르면 데이터 형식 우선순위 위가 있었습니다. 그래서 묵시적 변환이 일어나는 현상이 일어납니다.
해결 방법
가장 간단한 해결방법은 JDBC URL 에 sendStringParametersAsUnicode=false
를 추가하는 방법 입니다.
spring:
datasource:
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# 아래 sendStringParametersAsUnicode=false 추가
url: jdbc:sqlserver://localhost:1433;database=데이터베이스;sendStringParametersAsUnicode=false
이 설정 후 모든 String을 varchar로 매핑이 됩니다.
sendStringParametersAsUnicode=false
를 적으면 어떻게 될까요?
→ 우선순위에 따라 조건으로 들어온 Paramater가 형변환이 일어나는거라 Index에 영향이 없습니다.
→ (varchar → nvarchar) 로 되는 형변환이 문제 이기 때문에 Index유지 되고 성틍에 큰 문제가 안됩니다.그래도 나는 sendStringParametersAsUnicode=false
설정 후 nvarchar를 꼭 지정해서 사용하고 싶어 하는 경우
- JPA / Hibernate / JPQL
매핑하는 컬럼 필드에
@Nationalized
를 사용 하면 됩니다.@Nationalized @Colum(name ="Member_name") private String memberName;
- jdbcTemplate
String sql = "select * from Member where member_name = ?" Connection con = DataSourceUtils.getConnection(dataSource);; psmt = con.prepareStatement(sql); psmt.setString(1, memberName);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.query("select * from Member where member_name = ?", ps -> { ps.setNString(1, "Min"); }, rs -> { log.info(rs.getString("memberName")); });
Uploaded by Notion2Tistory v1.1.0