Spring + 다양한 ORM 을 사용하는 것에 대하여...

610 views
Skip to first unread message

임병인(포데브)

unread,
Jun 30, 2011, 9:01:22 AM6/30/11
to Korea Spring User Group
현재 프로젝트 개발환경의 주요프레임워크는 다음과 같습니다.

Spring MVC + Spring 3.0.5.RELEASE + Hibernate 3.6.2.Final(JPA2.0)

DBMS: MSSQL Server 2008

여기에 MVC + 3 Layered 아키텍처로 평이한 프로젝트입니다.

그런데 문제는 MSSQL + JPA에서 페이징에 대한 성능이슈가 발생하고 있습니다.
JPA의 EntityManager를 통해 JPQL을 생성하고 setMaxResult(), setFirstResult()등의
API를 사용하면 사용하지 않을 때보다 대략 3배정도의 성능차이를 보입니다. 생성된 SQL 구문을 실제 DB 브라우저로 조회를
실행하면 1초 미만입니다.
대상건수가 60만건정도이고 페이징 처리되는 건수가 대략 25만건 이상됩니다. 몇만건 정도되는 것은 눈에 띄게 성능차이를 보이지
는 않구요.

이런 상황을 혹시 경험하신분이 계시면 고견을 부탁드리겠습니다.

이 문제에 대한 해결가능한 방법으로
1. NativeQuery 를 사용한다.
2. iBATIS를 병행한다.
와 같이 두가지 방법을 고려하고 있습니다.
위의 두가지를 적용하더라도 MSSQL에서 페이징은 역시나 난관이긴 하지만 성능이 문제가 되지는 않을것 같습니다.
위의 두가지 방법을 포함하여 어떤 방법이 가장 효율적일까요?

Sungchul Park

unread,
Jun 30, 2011, 9:10:35 AM6/30/11
to ks...@googlegroups.com
신기하네요?
생성되는 SQL이 비효율적인 게 아니라 SQL에는 문제가 없는데 동일한 SQL의
실행 속도가 JPA를 통해 결과를 얻을 때와 직접 쿼리를 수행할 때 그렇게 많
이 차이가 난다는 건가요? (1초 v.s. 3초 정도?)

신승한

unread,
Jun 30, 2011, 8:03:21 PM6/30/11
to ks...@googlegroups.com


SQL실행 속도가 문제가 아니라 sql result를  bean으로 매핑하는 속도와 1차캐시 때문이 아닐까요?

대량의 배치를 돌려야 하는데 1차캐시를 활용하지 않는다면 옵션을 조절할 수 있는걸로 알고있습니다.


그리고 25만건씩이나 데이터를 가져온다면, 시스템이 ORM과는 궁합이 좋지 않아 보이네요.




2011년 6월 30일 오후 10:10, Sungchul Park <gyu...@gmail.com>님의 말:
--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+unsubscribe@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.


임병인(포데브)

unread,
Jun 30, 2011, 8:33:03 PM6/30/11
to Korea Spring User Group
제 질문에 관심을 가져주셔서 먼저 고맙습니다.
저도 신승환님이 지적하신것처럼 SQL의 문제(DBMS)라기보다는
객체매핑시간과 MSSQL에서 페이징을 위한 첫번째 데이터까지의
건너뛰기(skip) 기능이 없어서 발생하는 문제로 생각했습니다.
그래서 최대 갯수를 1로 주고 첫페이지를 가져오도록 했는데도
대상건수(카운트 조회로 알아냄)가 많으면 페이지나 최대갯수의
많고 적음에는 영향이 없었습니다. 물론 캐쉬설정은 Enhance로
설정을 했습니다.
요근래 Sybase나 MSSQL을 처음 다뤄보는거라서
DBMS특성을 파악하기 어려운 부분도 있습니다.

프로젝트 초기 이런상황을 예견했더라면 iBATIS(myBATIS)를
채택했을텐데 지금 돌리기엔 시간적인 여유가 없습니다.
혹 이런 문제를 경험하셨던 분들의 귀중한 경험을 공유해주시구요.
아키텍처 관점에서 두개 이상의 ORM을 적용하는 문제(어느 분들은
myBATIS를 ORM으로 분류하는걸 반대할수도 있으나 넓은 의미로
포함시켰습니다. )에 대한의견도 주시면 고맙겠습니다.
즉, 혼용하기보다는 NativeQuery가 좋다 등등. 감사합니다.

> > 그룹에서 탈퇴하려면 ksug+unsubscribe@googlegroups.**com<ksug%2Bunsu...@googlegroups.com>로
> > 이메일을 보내주세요.
> > 더 많은 옵션을 보려면http://groups.google.com/**group/ksug?hl=ko<http://groups.google.com/group/ksug?hl=ko>에서
> > 그룹을 방문하세요.

백기선

unread,
Jun 30, 2011, 8:52:31 PM6/30/11
to ks...@googlegroups.com


2011년 6월 30일 오후 10:01, 임병인(포데브) <brianlim...@gmail.com>님의 말:

현재 프로젝트 개발환경의 주요프레임워크는 다음과 같습니다.

Spring MVC + Spring 3.0.5.RELEASE + Hibernate 3.6.2.Final(JPA2.0)

DBMS: MSSQL Server 2008

여기에 MVC + 3 Layered 아키텍처로 평이한 프로젝트입니다.

그런데 문제는 MSSQL + JPA에서 페이징에 대한 성능이슈가 발생하고 있습니다.
JPA의 EntityManager를 통해 JPQL을 생성하고 setMaxResult(), setFirstResult()등의
API를 사용하면 사용하지 않을 때보다 대략 3배정도의 성능차이를 보입니다
.

=> 페이징 하실 때는 당연히 setMaxResult()와 setFirstResult()를 사용하셔야 합니다.
 
생성된 SQL 구문을 실제 DB 브라우저로 조회를
실행하면 1초 미만입니다.

=> 즉, 신승한님께서 지적해주신대로, ResultSet => 도메인 객체로 맵핑하는데 제법 오랜 시간이 걸린다는 것이겠죠. 

대상건수가 60만건정도이고 페이징 처리되는 건수가 대략 25만건 이상됩니다. 몇만건 정도되는 것은 눈에 띄게 성능차이를 보이지
는 않구요.

이런 상황을 혹시 경험하신분이 계시면 고견을 부탁드리겠습니다.

이 문제에 대한 해결가능한 방법으로
   1. NativeQuery 를 사용한다.
   2. iBATIS를 병행한다.

=> 성능 문제가 생긴 원인이 데이터 맵핑인데, 위 두 방법을 사용한다고 해결될까요? 글쎄요. 둘다 결과 받아서 도메인 객체로 맵핑할 때 결국 비슷하게 시간이 소요되지 않을까요.

그래서 대안으로 생각해본게 두 개 정도인데요.
1. 도메인 클래스로 맵핑하지 말기.. Map으로 받아서 걍 그대로 쓰세요. 하이버네이트에도 결과를 Map으로 받아오는 기능이 있습니다,
2. 데이터 맵핑 성능 개선
  - 구체적으로 "맵핑" 어디서 성능을 잡아먹는지 찾아봐야겠죠. 도메인 객체를 생성할 때? 아니면 리플렉션으로 필드를 알아낼 때? 그런 다음에 new로 객체 생성하는게 문제면 객체는 하나만 만들고 필드 속성을 다 refresh 시킨 다음에 저장시켜 보면 어떨지 싶구요.(id 값만 초기화 시키면 하이버는 새로 저장해야하는 객체인줄 알테니까요.) 리플렉션이 문제면 ASM으로 필드를 알아내면 어떨지 싶습니다.

흠냐.. 원래는 제가 해볼려고 했던건데... 먼저 해보시고 알려주셔도 좋겠습니다.


와 같이 두가지 방법을 고려하고 있습니다.
위의 두가지를 적용하더라도 MSSQL에서 페이징은 역시나 난관이긴 하지만 성능이 문제가 되지는 않을것 같습니다.
위의 두가지 방법을 포함하여 어떤 방법이 가장 효율적일까요?
--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.

더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.




--
좋은 하루 되세요~

백기선

unread,
Jun 30, 2011, 8:58:49 PM6/30/11
to ks...@googlegroups.com


2011년 7월 1일 오전 9:33, 임병인(포데브) <brianlim...@gmail.com>님의 말:

제 질문에 관심을 가져주셔서 먼저 고맙습니다.
저도 신승환님이 지적하신것처럼 SQL의 문제(DBMS)라기보다는
객체매핑시간과 MSSQL에서 페이징을 위한 첫번째 데이터까지의
건너뛰기(skip) 기능이 없어서 발생하는 문제로 생각했습니다.
그래서 최대 갯수를 1로 주고 첫페이지를 가져오도록 했는데도
대상건수(카운트 조회로 알아냄)가 많으면 페이지나 최대갯수의
많고 적음에는 영향이 없었습니다. 물론 캐쉬설정은 Enhance로
설정을 했습니다.
요근래 Sybase나 MSSQL을 처음 다뤄보는거라서
DBMS특성을 파악하기 어려운 부분도 있습니다.

 프로젝트 초기 이런상황을 예견했더라면 iBATIS(myBATIS)를
채택했을텐데 지금 돌리기엔 시간적인 여유가 없습니다.
혹 이런 문제를 경험하셨던 분들의 귀중한 경험을 공유해주시구요.
아키텍처 관점에서 두개 이상의 ORM을 적용하는 문제(어느 분들은
myBATIS를 ORM으로 분류하는걸 반대할수도 있으나 넓은 의미로
포함시켰습니다. )에 대한의견도 주시면 고맙겠습니다.
즉, 혼용하기보다는 NativeQuery가 좋다 등등. 감사합니다.

=> 사내에서 혼용하는 방법도 검토했었습니다. 이유는 하이버네이트에서 네이티브 쿼리를 동적으로 생성할 수 없었기 때문이죠. iBatis는 XML 문법으로 모든 쿼리를 동적으로 생성할 수 있지만 하이버네이트는 Criteria API로 처리하지 못하는 네이티브 쿼리는 참.. 난감하거든요. 문자열을 직접 지지고 볶아야 하는데.. 그래서 그런 쿼리를 iBatis XML로 정의하고, 하이버네이트에서 네이티브 쿼리 호출하는 부분에 iBatis를 연동해서 처리하는 방식을 고안했는데요. 그닥..... 개인적으로는  관리 포인트가 더블+알파(하이버, 아이바, 연동부분)가 되버려서 별로입니다. 

네이티브 쿼리가 얼마나 많으냐에 따라 달라지겠지만, 몇개 되지 않는다면 그냥 자바로 문자열을 잘 다루시는게 어떨지 싶습니다.

정상혁님 글 중에 그루비로 네이티브 쿼리를 작성하는 글도 있었는데요. 그것도 역시 개인적으로는 관리 포인트가.. 언어 차원으로 늘어나서... 네이티브 쿼리 비율이 높지 않다면 그냥 자바로 간단한 인터페이스 만들어서, 문자열 잘 다루는 클래스로 뚝딱 뚝딱 하시는게 좋을 것 같습니다.


그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.

더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.




--
좋은 하루 되세요~

Sungchul Park

unread,
Jun 30, 2011, 9:15:06 PM6/30/11
to ks...@googlegroups.com

> => 사내에서 혼용하는 방법도 검토했었습니다. 이유는 하이버네이트에서 네
> 이티브 쿼리를 동적으로 생성할 수 없었기 때문이죠. iBatis는 XML 문법으
> 로 모든 쿼리를 동적으로 생성할 수 있지만 하이버네이트는 Criteria API로
> 처리하지 못하는 네이티브 쿼리는 참.. 난감하거든요. 문자열을 직접 지지
> 고 볶아야 하는데.. 그래서 그런 쿼리를 iBatis XML로 정의하고, 하이버네
> 이트에서 네이티브 쿼리 호출하는 부분에 iBatis를 연동해서 처리하는 방식
> 을 고안했는데요. 그닥..... 개인적으로는 관리 포인트가 더블+알파(하이
> 버, 아이바, 연동부분)가 되버려서 별로입니다.
동적 쿼리 때문이라면 iBatis는 정말 비추입니다.
XML 같은 외부 파일에 SQL을 모아 놔야 한다면 차라리 freemarker나 velocity
사용해서 하나 간단히 만드시고요. 그렇지 않다면 Query Builder를 만들거나
적당한 놈을 구해서 사용하시는 쪽이 훨씬 낫다고 봅니다.

> 정상혁님 글 중에 그루비로 네이티브 쿼리를 작성하는 글도 있었는데요. 그
> 것도 역시 개인적으로는 관리 포인트가.. 언어 차원으로 늘어나서... 네이
> 티브 쿼리 비율이 높지 않다면 그냥 자바로 간단한 인터페이스 만들어서,
> 문자열 잘 다루는 클래스로 뚝딱 뚝딱 하시는게 좋을 것 같습니다.

그루비를 DSL로 사용한다고 꼭 그루비를 알아야 할 필요는 없지 않을까 생각
합니다. XML 쓴다고 XML 파싱하는 법 알아야 하는 건 아니니까요. 정상혁님에
게 그루비 DSL 방식의 쿼리 빌더를 만들어 달라고 하신 후에 오픈 소스로 풀
고 책임지라고 하시면 됩니다. ^^--

Sungchul Park

unread,
Jun 30, 2011, 9:18:17 PM6/30/11
to ks...@googlegroups.com

> SQL실행 속도가 문제가 아니라 sql result를 bean으로 매핑하는 속도와 1
> 차캐시 때문이 아닐까요?
> 대량의 배치를 돌려야 하는데 1차캐시를 활용하지 않는다면 옵션을 조절할
> 수 있는걸로 알고있습니다.
> 그리고 25만건씩이나 데이터를 가져온다면, 시스템이 ORM과는 궁합이 좋지
> 않아 보이네요.
잉? 페이징으로 한번에 읽어오는 데이터 개수가 25만건이라는 뜻인가요? 그렇
다면 ORM 대상이라고 보기엔...

백기선

unread,
Jun 30, 2011, 9:19:57 PM6/30/11
to ks...@googlegroups.com


2011년 7월 1일 오전 10:18, Sungchul Park <gyu...@gmail.com>님의 말:
=> 저도 이부분이 참 의아했는데.. 도대체 한 화면에서 25만건을 어떻게 보죠?? 매트릭스 직원들인가.. 흠;;




--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+unsubscribe@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.




--
좋은 하루 되세요~

신승한

unread,
Jun 30, 2011, 9:21:37 PM6/30/11
to ks...@googlegroups.com

ㅎㅎ 누군가 생각하긴 했군요.

http://ilyasterin.com/blog/2009/07/groovy-sql-builder.html

잘만 수정하면 쓸만할지도 모르겠네요.



지난 프로젝트에서 HQL빌더를 만들어서 썼었는데, 시간상 개인이 범용적으로 만들어 쓰기에는 무리가 있더군요.

누가 안만들어주나..


2011년 7월 1일 오전 10:15, Sungchul Park <gyu...@gmail.com>님의 말:

--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+unsubscribe@googlegroups.com로 이메일을 보내주세요.

백기선

unread,
Jun 30, 2011, 9:23:28 PM6/30/11
to ks...@googlegroups.com


2011년 7월 1일 오전 10:15, Sungchul Park <gyu...@gmail.com>님의 말:


=> 사내에서 혼용하는 방법도 검토했었습니다. 이유는 하이버네이트에서 네 이티브 쿼리를 동적으로 생성할 수 없었기 때문이죠. iBatis는 XML 문법으 로 모든 쿼리를 동적으로 생성할 수 있지만 하이버네이트는 Criteria API로 처리하지 못하는 네이티브 쿼리는 참.. 난감하거든요. 문자열을 직접 지지 고 볶아야 하는데.. 그래서 그런 쿼리를 iBatis XML로 정의하고, 하이버네 이트에서 네이티브 쿼리 호출하는 부분에 iBatis를 연동해서 처리하는 방식 을 고안했는데요. 그닥..... 개인적으로는  관리 포인트가 더블+알파(하이 버, 아이바, 연동부분)가 되버려서 별로입니다.
동적 쿼리 때문이라면 iBatis는 정말 비추입니다.
XML 같은 외부 파일에 SQL을 모아 놔야 한다면 차라리 freemarker나 velocity 사용해서 하나 간단히 만드시고요. 그렇지 않다면 Query Builder를 만들거나 적당한 놈을 구해서 사용하시는 쪽이 훨씬 낫다고 봅니다.

=> 프리마커나 벨로서티도 검토했었는데요. 제가 결정한게 아니라서 ㅋㅋ 정말 저런 툴이 필요하면 iBatis를 쓰던 프리마커/벨로서티를 쓰던.. 저에겐 다 비슷 비슷해 보이네요.
 

정상혁님 글 중에 그루비로 네이티브 쿼리를 작성하는 글도 있었는데요. 그 것도 역시 개인적으로는 관리 포인트가.. 언어 차원으로 늘어나서... 네이 티브 쿼리 비율이 높지 않다면 그냥 자바로 간단한 인터페이스 만들어서, 문자열 잘 다루는 클래스로 뚝딱 뚝딱 하시는게 좋을 것 같습니다.
그루비를 DSL로 사용한다고 꼭 그루비를 알아야 할 필요는 없지 않을까 생각 합니다. XML 쓴다고 XML 파싱하는 법 알아야 하는 건 아니니까요. 정상혁님에 게 그루비 DSL 방식의 쿼리 빌더를 만들어 달라고 하신 후에 오픈 소스로 풀 고 책임지라고 하시면 됩니다. ^^--

=> 그루비를 알아야 하는 부담이 아니라요. 그루비가 잘 안 돌아간다는.. 메이븐 플러그인까지 해서 서비스쪽에서 어찌저찌 해봤던것 같은데, 정상혁님 글 보고 해봐도 잘 안된다고 해서 걍 포기한듯해요. 어떤 이유에서건 적용하기 쉽지 않다면 포기하는 것도 적절한 선택이겠죠. 

 
--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+unsubscribe@googlegroups.com로 이메일을 보내주세요.

더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.




--
좋은 하루 되세요~

Sanghyuk Jung

unread,
Jun 30, 2011, 9:34:33 PM6/30/11
to ks...@googlegroups.com
위에서 잠깐 언급된, 쿼리 관리에 groovy를 쓰는 방법은 아래 정리되어 잇습니다.
 
 
딱히 groovy를 알아야되는 기법도 아니고, 그냥 java에 따옴표 3개가 없어서 시도한 방법이였습니다~ 언어가 하나더 추가된다고 해도 개발자에게 부담되는 수준은 아니라고 생각했는데, 처음에 eclipse plugin과 maven plugin 설정하는 부분에서 걸리시는 분들도 있었나보네요.
 
암튼 이런 plugin 추가 없이 java에서 바로 문자열로 처리하는 방식도 좋다고 생각하고, 어서빨리 java에도 따옴표 3개가 들어가서 굳이 이런 사소한 문법 쓰려고 groovy를 동원하는 일이 없어졌으면 좋겠네요 ^^; 
 
 
2011년 7월 1일 오전 10:23, 백기선 <whites...@gmail.com>님의 말:
그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.

임병인(포데브)

unread,
Jul 1, 2011, 6:31:27 AM7/1/11
to Korea Spring User Group

On 7월1일, 오전10시19분, 백기선 <whiteship2...@gmail.com> wrote:
> 2011년 7월 1일 오전 10:18, Sungchul Park <gyu...@gmail.com>님의 말:
>
>
>
> > SQL실행 속도가 문제가 아니라 sql result를 bean으로 매핑하는 속도와 1 차캐시 때문이 아닐까요?
>
> >> 대량의 배치를 돌려야 하는데 1차캐시를 활용하지 않는다면 옵션을 조절할 수 있는걸로 알고있습니다.
> >> 그리고 25만건씩이나 데이터를 가져온다면, 시스템이 ORM과는 궁합이 좋지 않아 보이네요.
>
> > 잉? 페이징으로 한번에 읽어오는 데이터 개수가 25만건이라는 뜻인가요? 그렇 다면 ORM 대상이라고 보기엔...
>
> => 저도 이부분이 참 의아했는데.. 도대체 한 화면에서 25만건을 어떻게 보죠?? 매트릭스 직원들인가.. 흠;;

ㅎㅎ 내용이 전달되면서 앞글과 다르게...
전체 데이터 건수가 60여만건이고 대략 하루에 2-3천건씩 추가됩니다.
특별조회조건없이 기본조회조건으로 검색하면 25만건 정도가 검색되는데
이 건수가 너무 많으니 페이징으로 처리를 하고 있습니다.
즉, 먼저 조회대상건수를 구하고 그 다음 실제 페이징처리용 데이터를(기본 10건)
조회하고 있습니다. 이때 문제가 JPA API를 사용하면 속도가 현저히 떨어진다는거죠.
생성된 SQL을 보면 top이 정상적으로 붙어 있구요. 오라클의 rownum이나 MySql의 limit 같은...
(Sybase나 MSSQL 은 top을 사용)
출력된 SQL로그를 디비브라우저로 실행하여 조회하면 1초미만이구요.
일단 객체매핑비용이 발생하긴하나 그닥크지 않은게 실제 매핑건수는
최대건수(기본10건) 만큼만 생성되니까요.
조회건수가 몇천건정도만 조회되도록 조건을 주고
페이징 조건 즉, setFirstResult(), setMaxResult()를 사용하지
않으면 1초이내 응답입니다. 그러므로 매핑의 문제는 아닌듯합니다.


>
>
>
> > --
> > Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
> > 이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.

> > 그룹에서 탈퇴하려면 ksug+unsubscribe@googlegroups.**com<ksug%2Bunsu...@googlegroups.com>로
> > 이메일을 보내주세요.

임병인(포데브)

unread,
Jul 1, 2011, 6:36:35 AM7/1/11
to Korea Spring User Group
많은 분들의 의견이 대체로 네이티브쿼리로 모아지는 것같네요.
다만 문자열조합방법을 StringBuilder를 쓰느냐
Groovy를 쓰느냐인데 나중에 고객사 인수를 위해
그루비 사용은 ㅎㅎㅎ
처리후 결과를 공유하도록 하겠습니다.
고맙습니다.

On 7월1일, 오전10시34분, Sanghyuk Jung <bene...@gmail.com> wrote:
> 위에서 잠깐 언급된, 쿼리 관리에 groovy를 쓰는 방법은 아래 정리되어 잇습니다.
>
> http://benelog.egloos.com/2708621
>
> 딱히 groovy를 알아야되는 기법도 아니고, 그냥 java에 따옴표 3개가 없어서 시도한 방법이였습니다~ 언어가 하나더 추가된다고 해도
> 개발자에게 부담되는 수준은 아니라고 생각했는데, 처음에 eclipse plugin과 maven plugin 설정하는 부분에서 걸리시는
> 분들도 있었나보네요.
>
> 암튼 이런 plugin 추가 없이 java에서 바로 문자열로 처리하는 방식도 좋다고 생각하고, 어서빨리 java에도 따옴표 3개가
> 들어가서 굳이 이런 사소한 문법 쓰려고 groovy를 동원하는 일이 없어졌으면 좋겠네요 ^^;
>

> 2011년 7월 1일 오전 10:23, 백기선 <whiteship2...@gmail.com>님의 말:


>
>
>
>
>
> > 2011년 7월 1일 오전 10:15, Sungchul Park <gyu...@gmail.com>님의 말:
>
> >> => 사내에서 혼용하는 방법도 검토했었습니다. 이유는 하이버네이트에서 네 이티브 쿼리를 동적으로 생성할 수 없었기 때문이죠.
> >>> iBatis는 XML 문법으 로 모든 쿼리를 동적으로 생성할 수 있지만 하이버네이트는 Criteria API로 처리하지 못하는 네이티브
> >>> 쿼리는 참.. 난감하거든요. 문자열을 직접 지지 고 볶아야 하는데.. 그래서 그런 쿼리를 iBatis XML로 정의하고, 하이버네
> >>> 이트에서 네이티브 쿼리 호출하는 부분에 iBatis를 연동해서 처리하는 방식 을 고안했는데요. 그닥..... 개인적으로는 관리 포인트가
> >>> 더블+알파(하이 버, 아이바, 연동부분)가 되버려서 별로입니다.
>
> >> 동적 쿼리 때문이라면 iBatis는 정말 비추입니다.
> >> XML 같은 외부 파일에 SQL을 모아 놔야 한다면 차라리 freemarker나 velocity 사용해서 하나 간단히 만드시고요.
> >> 그렇지 않다면 Query Builder를 만들거나 적당한 놈을 구해서 사용하시는 쪽이 훨씬 낫다고 봅니다.
>
> > => 프리마커나 벨로서티도 검토했었는데요. 제가 결정한게 아니라서 ㅋㅋ 정말 저런 툴이 필요하면 iBatis를 쓰던 프리마커/벨로서티를
> > 쓰던.. 저에겐 다 비슷 비슷해 보이네요.
>
> >> 정상혁님 글 중에 그루비로 네이티브 쿼리를 작성하는 글도 있었는데요. 그 것도 역시 개인적으로는 관리 포인트가.. 언어 차원으로
> >>> 늘어나서... 네이 티브 쿼리 비율이 높지 않다면 그냥 자바로 간단한 인터페이스 만들어서, 문자열 잘 다루는 클래스로 뚝딱 뚝딱 하시는게
> >>> 좋을 것 같습니다.
>
> >> 그루비를 DSL로 사용한다고 꼭 그루비를 알아야 할 필요는 없지 않을까 생각 합니다. XML 쓴다고 XML 파싱하는 법 알아야 하는
> >> 건 아니니까요. 정상혁님에 게 그루비 DSL 방식의 쿼리 빌더를 만들어 달라고 하신 후에 오픈 소스로 풀 고 책임지라고 하시면 됩니다.
> >> ^^--
>
> > => 그루비를 알아야 하는 부담이 아니라요. 그루비가 잘 안 돌아간다는.. 메이븐 플러그인까지 해서 서비스쪽에서 어찌저찌 해봤던것
> > 같은데, 정상혁님 글 보고 해봐도 잘 안된다고 해서 걍 포기한듯해요. 어떤 이유에서건 적용하기 쉽지 않다면 포기하는 것도 적절한
> > 선택이겠죠.
>
> >> --
> >> Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
> >> 이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.

> >> 그룹에서 탈퇴하려면 ksug+unsubscribe@googlegroups.**com<ksug%2Bunsu...@googlegroups.com>로
> >> 이메일을 보내주세요.

KwonNam Son

unread,
Jul 1, 2011, 8:41:20 AM7/1/11
to ks...@googlegroups.com
Hibernate가 생성한 쿼리를 쿼리툴로 테스트해보면 1초 미만으로 결과가 나왔지만 Hibernate에서 직접 테스트 할 때는 매우 느렸다고 하셨는데요.
그렇다면 제가 보기엔 제대로 테스트를 안했을 가능성이 높습니다.

Hibernate는 PreparedStatement 로 top 명령의 값을 설정했을 것입니다.
하지만 쿼리툴로 테스트하실 때는 top 뒤에 값을 직접 명시를 했을 것으로 예상됩니다.

여기서 조건의 차이가 발생합니다.

즉, 하나는 PreparedStatement로 top의 조건을 줬고 나머지 하나는 쿼리툴에서 숫자값을 명시했다는 차이 가 발생하게 되고 이 상황은 결코 완전히 동일한 테스트를 수행했다고 볼 수 없습니다.

그래서 "mssql top prepared statement slow" 로 구글 검색을 해보았습니다.

바로 결과가 나오네요.

https://forum.hibernate.org/viewtopic.php?t=927743
http://www.sql-server-performance.com/forum/threads/bad-jdbc-hibernate-peformance-for-sql-server-2000.18350/

http://www.hibernate.org/74.html 에 문제의 핵심 원인이 설명이 돼 있는 것 같은데... 문서가 지워졌습니다. --; 그래서 실제 이유가 무엇인지는 추측할 수밖에 없는데요..

아무튼 MS에서 제공한 JDBC 드라이버의 경우 특정 버전에서 PreparedStatement 사용시 성능 저하 현상이 발생하는 것으로 판단됩니다.
그리고 유니코드와의 연관성도 좀 있어보이네요.

MS제공 드라이버일 경우 최신 버전으로 JDBC 드라이버의 버전을 변경해보시거나, 아니면 JTDS 의 MSSQL JDBC 드라이버를 사용해보십시오.

hibernate mssql top prepared statement slow 를 검색어로 다른 자료들을 더 찾아볼 수 있을 것으로 보입니다.

2011년 7월 1일 오후 7:36, 임병인(포데브) <brianlim...@gmail.com>님의 말:
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.




--
* 까먹지말자! http://kwon37xi.egloos.com

KwonNam Son

unread,
Jul 1, 2011, 8:58:36 AM7/1/11
to ks...@googlegroups.com
http://www.thatsjava.com/jdbc/98111/ 여기에 좀더 정확한 설명이 있는 것으로 보입니다.

MSQL/PreparedStatement/유니코드가 주범인게 맞는 것 같구요, 그러나 매우 오래전에 발생하던 것으로 최신버전 MSSQL JDBC 드라이버에서는 문제가 해결됐을것으로 보입니다.

왜냐하면..

저도 2년전부터 MSSQL에 MS JDBC Driver(당시 최신버전)와 jTDS JDBC Driver 모두를 가지고 작업을 했었는데 아무런 문제도 겪은적이 없거든요.

2011년 7월 1일 오후 9:41, KwonNam Son <kwon...@gmail.com>님의 말:

최영목

unread,
Jul 1, 2011, 11:58:19 AM7/1/11
to ks...@googlegroups.com
안녕하세요? 질문 글을 올린 임병인 차장님과 같은 프로젝트를 진행하고 있는 넥스트리소프트(주) 최영목 대리라고 합니다. ^^

권남님께서 언급하신 방법도 한번 확인을 해봐야겠네요. ^^ 왜냐하면 처음 테스트를 진행할 당시 setFirstResult()는 성능에 영향을 주지 않았으나,  setMaxResult()를 사용하였을 때 급격히 성능저하가 일어났던 현상을 발견하였습니다.

MSSQL에서는 setFirstResult()는 MSSQL에서는 쿼리로 매칭되는 부분이 없어서(top 키워드밖에 없으므로) 성능에 영향을 주지 않았을 가능성도 있네요. 

maven으로 가져온 mssql jdbc의 버전을 한번 확인해보도록 하겠습니다. 

아, 그리고 테스트할 때 테스트 대상 dialect은 org.hibernate.dialect.SQLServerDialect과 org.hibernate.dialect.SQLServer2008Dialect으로 테스트를 했었습니다. 

이상하게도 MSSQL 2005부터는 row_number()가 도입되었는데 org.hibernate.dialect.SQLServer2005Dialect에 있던 row_number() 지원이 org.hibernate.dialect.SQLServer2008Dialect에는 빠져있어서 MSSQL 2008에서는 row_number()가 빠져있다는 생각을 했었습니다.
protected static void insertRowNumberFunction(StringBuilder sql, CharSequence orderby);

참조 url :

그런데 MSSQL 2008에도 row_number()는 있더군요. (오늘 다시 찾아보고 알았습니다. ^^;;;)

그런데 웃기게도 분명 3.6API와 현재 사용하고 있는 Hibernate 3.6.2.Final에는 2008Dialect이 SQLServerDialect을 상속받고 있습니다. 하지만 실세 github에 있는 소스내용을 살펴보면 2008Dialect이 2005Dialect를 상속받고 있네요 ㅡㅅ ㅡ;;

그 부분에 대한 수정은 작년말에 있었습니다.

참조 url :

좀 더 찾아보니 이 부분은 hibernate 4.0에 반영된 모양입니다.
참조 url : 

만약 현재의 퍼포먼스 문제가 권남님께서 말씀하신 문제이고, 현재 3.6.2버전의 2008Dialect를 조금 수정한다면 더 좋은 성능을 기대할수도 있을 것 같습니다. 

어떤 분은 이렇게 쓰기도 하시네요

일단 지적하신 부분을 테스트한 후 2008Dialect를 건의드리고 그 결과를 공유하도록 하겠습니다. 
모든 분들의 조언 감사드립니다. ^^


2011년 7월 1일 오후 9:58, KwonNam Son <kwon...@gmail.com>님의 말:

임병인(포데브)

unread,
Jul 1, 2011, 10:54:43 PM7/1/11
to Korea Spring User Group
문제해결의 단초를 주셔서 정말 고맙습니다.
저도 한 검색한다고 생각했는데 prepared는 전혀 생각하지 못했네요.

일단 유니코드 문제는 아닌듯 합니다.
디비에 유니코드 설정을 하지 않았고 유니코드 컬럼도 안쓰고
무엇보다 유니코드 설정방법을 찾을수가 없었습니다.
(ㅎㅎ 이번에 처음으로 MSSQL2008Server 를 사용해봤습니다. )
워낙 짧은 프로젝트(3개월)에 개발범위가 많은지라 제가 문제해결의시간을
하루이내로 통제하고 그보다 더걸리면 구현가능한 방법을 찾아
일단은 동작가능한 상태를 만들도록 했기때문에 문제가 발생하지 않은
디비특성은 잠시 고려대상에서 제외했습니다.
아직 한글문제(유니코드문제)는 발생하지 않았습니다.
Sybase는 JDBC 컨넥션을 구할때 속성으로 charset을 지정해서
한글문제를 해결했었는데 MSSQL은 별도 처리를 하지않아도
되더군요. ㅋㅋ 이제 한글지원이 기본인가? 라는 착각도...

네이티브쿼리나 기술중복을 피하면서 해결방법이 있을지도 모른다는
희망으로 기분이 정말좋아지네요.
감사합니다.


On 7월1일, 오후9시41분, KwonNam Son <kwon3...@gmail.com> wrote:
> Hibernate가 생성한 쿼리를 쿼리툴로 테스트해보면 1초 미만으로 결과가 나왔지만 Hibernate에서 직접 테스트 할 때는 매우
> 느렸다고 하셨는데요.
> 그렇다면 제가 보기엔 제대로 테스트를 안했을 가능성이 높습니다.
>
> Hibernate는 PreparedStatement 로 top 명령의 값을 설정했을 것입니다.
> 하지만 쿼리툴로 테스트하실 때는 top 뒤에 값을 직접 명시를 했을 것으로 예상됩니다.
>
> 여기서 조건의 차이가 발생합니다.
>

> *즉, 하나는 PreparedStatement로 top의 조건을 줬고 나머지 하나는 쿼리툴에서 숫자값을 명시했다는 차이* 가 발생하게
> 되고 이 상황은 *결코 완전히 동일한 테스트를 수행했다고 볼 수 없습니다.*


>
> 그래서 "mssql top prepared statement slow" 로 구글 검색을 해보았습니다.
>
> 바로 결과가 나오네요.
>

> https://forum.hibernate.org/viewtopic.php?t=927743http://www.sql-server-performance.com/forum/threads/bad-jdbc-hibernat...
>
> http://www.hibernate.org/74.html<http://www.hibernate.org/74.html#A15> 에


> 문제의 핵심 원인이 설명이 돼 있는 것 같은데... 문서가 지워졌습니다. --; 그래서 실제 이유가 무엇인지는 추측할 수밖에 없는데요..
>

> *아무튼 MS에서 제공한 JDBC 드라이버의 경우 특정 버전에서 PreparedStatement 사용시 성능 저하 현상이 발생하는 것으로
> 판단됩니다.*


> 그리고 유니코드와의 연관성도 좀 있어보이네요.
>

> *MS제공 드라이버일 경우 최신 버전으로 JDBC 드라이버의 버전을 변경해보시거나, 아니면 JTDS 의 MSSQL JDBC 드라이버를
> 사용해보십시오.*


>
> hibernate mssql top prepared statement slow 를 검색어로 다른 자료들을 더 찾아볼 수 있을 것으로
> 보입니다.
>

> 2011년 7월 1일 오후 7:36, 임병인(포데브) <brianlim.next...@gmail.com>님의 말:

> * 까먹지말자!http://kwon37xi.egloos.com

KwonNam Son

unread,
Jul 7, 2011, 9:58:26 PM7/7/11
to ks...@googlegroups.com
아주 많은 사람들이 문제 해결에 참여한 쓰레드인데, 최종적으로 어떻게 차리하셨고 왜 그런 결정을 내렸는지 공유해 주실 수 있을까요?
궁금하네요.

2011년 7월 2일 오전 11:54, 임병인(포데브) <brianlim...@gmail.com>님의 말:
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.

최영목

unread,
Jul 8, 2011, 3:54:05 AM7/8/11
to ks...@googlegroups.com
권남님, 답변이 늦어 죄송합니다.

현재 말씀드리기 힘든 프로젝트상황 (비즈니스적인... 어떤 것인지 이해하시리라 생각됩니다.) 때문에 아직 이 쓰레드에 대한 적용이 stop된 상태입니다. ㅠㅠ
해당 부분의 반영 결과를 이 쓰레드를 통해서 공유하도록 하겠습니다. 


2011년 7월 8일 오전 10:58, KwonNam Son <kwon...@gmail.com>님의 말:
Reply all
Reply to author
Forward
0 new messages