Site Search :
Standard Enterprise XML Methodology Pattern Setting Tunning Other
Article Contributors
GuestBook
Javapattern Maven
XSourceGen Dev
JetSpeed Test
JLook Image
jLook Family Site


Java JDBC Performance Tip(1)-Select Speed up!
 
자바쪽의 배치프로그램을 먼저 보기 전에 우선 워밍업으로 대량 데이터의 select쿼리시에 속도를 올릴수 있는 방법에 대하여 살펴본다. ( 2003/04/14 ) 1277
Written by ienvyou - 최지웅
1 of 1
 

이번 아티클에서는 자바에서의 배치작업에 대하여 논하여 보자. 전부터 이부분에 대하여 
작성을 한다고 직접 적어놓고서 이제야 만들어 내는 놀새의 게으름을 이해해주기 바란다.
왜냐~~ 요즘 너무 바쁘기 때문에.. ^^

이런거 이미 알고 있으면서도 혼자만의 기술인냥 숨기고 있는 사람들이 있을까봐 열심히 만들어서
아티클로 쓴다. 혼자 알고 있으면 뭐하리요. 인터넷은 헛빵으로 있는 것이 아니다. 정보의 바다인
것이다.

지금 시간이 없다.. 바로 시작한다.  

일전 방명록에 이런 작업을 하는 분의 문의가 있었다. 요약하면 다음과 같은데 "당신의 연구성과를
잘 보고 있다, 우리 사이트는 배치작업을 Pro*C로 하고 front-end단은 자바로 한다. 하고 싶은
말인즉은 배치도 자바로 짜고 싶다. 퍼포먼스를 나게 하는 방법을 알려달라" 라는 것이 요지였다.

작년말의 프로젝트에서도 배치를 하긴 했지만 그때는 java data를 읽어내어 Visual Basic에서 처리하는
배치프로그램이어서 자바보다는 VB에 가까운 형태였고, 고생도 많이 했다.

하지만 이번에는 순수 자바배치를 이용하도록 한다. 당연히 transtion상황하이므로 insert, update, delete에
관한 것임을 염두에 두어야 한다.

우선 워밍업으로 select를 빨리 해올 수 있는 방법을 잠깐 보도록 하자.

단~ 우선 알아두어야 할 것은 이번 아티클은 오라클을 이용한 샘플임을 알아두도록 하자.

▶ Select Query speed up!

Database record select속도를 높일 수 있다?  흠.
오라클 데이터베이스의 메모리 구조에서 사용하는 영역을 Oracle JDBC까지 연결시켜 보면 쉽게 보이는
것이다. 보통 오라클같은 경우 Software Code Areas, P.G.A (Program Global Area), 
S.G.A (System Global Area) 로 나눌수 있다

간략하게 나마 설명을 해보자면 

1) SoftWare Code Areas.
 오라클의 실행 모듈들이 메모리에 할당되는 공간이다.
 일반 유저 프로그램이 접근할 수 없고, 크기는  O/S 에 따라 약간씩 다르지만 Virtual Memory 에 위
 치하게 된다. 

2) S.G.A ( System Global Area )
 오라클 인스턴스의 한 부분으로 인스턴스가 기동 (Startup) 할때 메모리에 잡히게 되는 작업 영역이
 다.  이 영역은 오라클이 기동중에 사용되는 데이타나 각종 정보들, 그리고 일반 유저들의 모든 SQL
 문장들을 이곳에서 수행한다.  주로, Real Memory 에 위치하게 된다.

3) P.G.A ( Program Global Areas ) 
 유저가 요청한  SQL 문장을 처리하기 위해서 각 세션마다 선언된 변수 값들을 임시로 저장하는 영역
 으로, DisConnect 하면, 자동으로 Release 된다

자, 그러면 우리가 사용하는 JDBC의 연결영역은 어떻게 될것인가? 

위의 설명에서 처럼 SGA를 사용할 것 같다. SGA는 Data Buffer Cache를 가지고 있게 되는 데 이것은 
SQL 문장을 실행할때 필요한 데이타를 디스크에서 SGA 영역으로 읽어 들이는 곳이다. 
여기에는 변경된 데이터뿐만 아니라 변경되지 않는 데이터도 가지고 있는데, 이는 수행속도 향상을
위해 디스크 입출력 보다는 메모리 Access를 하게 하기 위함이다.
이 영역이 크면 그만큼 많은 데이타를 SGA 영역에 올려놓을 수 있으므로 메모리에서 바로 읽을 수 
있는 Hit 율이 높아진다. 그러나, 이 영역이 너무 작으면 스와핑(Swapping) 이 많이 발생되므로 
시스템의 성능에 영향을 준다. 조회 속도를 높이기 위해선 이 영역을 충분히 크게 해야 하는데
이곳을 걸고 넘어질 수 있는 Java API가 ResultSet 클래스의 setFetchSize(int rows) 메소드이다.
즉 JDBC Driver가 ResultSet을 통해서 가져올 데이터의 fetch크기를 결정하게 하는 것이다.

퍼포먼스에서 항상 나오는 이야기이지만 이러한 값들은 너무 커도 안되고 너무 작아도 안된다는것이다.
데이터베이스마다 최적의 성능을 나타내는 값으로 세팅되어져야 함은 물론이다.
또한 0 <= rows <= Statement.getMaxRows() 임은 당연하겠다.

적은 양의 데이터베이스의 select 쿼리시에 위의 fetch size에 대한 결정은 별 차이점을 드러내지 않지만
대량의 데이터를 조회하는 ResultSet의  경우 그 차이는 점점 극명하게 나타나는 것을 확인할 수 있다.

간단한 예제를 보겠다.
이 예제에서 사용되는 abt140이란 테이블은 현재 6,511,102건의 데이터를 가지고 있다.
fetch size를 지정하고 안하고 의 경우를 통하여 결과값을 보도록 하겠다.

import java.sql.*;
import java.io.*;

class FetchSizeTest {
    public static void main(String[] args) throws Exception {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        String url ="jdbc:oracle:thin:@192.168.0.137:1521:abn";
        Connection conn = DriverManager.getConnection(url,"abs","abs");
        String query = " select * from abt140";
        PreparedStatement stmt = conn.prepareStatement(query);
        long start = System.currentTimeMillis();
        ResultSet rs = stmt.executeQuery();
        rs.setFetchSize(10000);
        while(rs.next()) {
            new String("xx");
        }
        System.out.println("Time elapsed : " + (System.currentTimeMillis() - start));
        rs.close();
        stmt.close();
        conn.close(); 
    }
}
위 프로그램에서 setFetchSize를 적용시키기 전과 후의 결과값은 다음과 같다. Fetch Size 적용안할 경우 : Time elapsed --> 423038 Fetch Size를 10000 rows로 적용할 경우 : Time elapsed --> 101556 위의 경우 속도차이가 거의 4배가 나는 것을 볼 수 있으며, 꼭 10000개의 record를 fetch로 하는게 최상의 퍼포먼스가 아님을 명심해두자.
 
1
References
 
Copyright ⓒ 2003 www.javapattern.info & www.jlook.com, an jLOOK co.,LTD