잘알고 있다고 생각들 하는 JDBC ...
JDBC 전문가가 이야기하는거 한번 들어보세요.. ^^
Posted by 아름프로
예전의 JDBC 방식으로 개발하시는 분들 보면..
대부분 그냥 쿼리를 두번 처리하게 돌려서 하곤 합니다.
그런데 문제는 이렇게 처리하였을 때, rollback이 안되서
데이터가 이상하게 꼬일 수가 있답니다.
(릴레이이션을 잘 잡아놨다면 DB상에서 에러를 내주지만.. )
어쨌든, 그러한 경우에 유용하게 쓰일 수 있는 방법입니다.

=====================================
con.setAutoCommit(false);
Statement stmt = con.createStatement();
stmt.addBatch("INSERT INTO COFFEES " +
                "VALUES('Amaretto', 49, 9.99, 0, 0)");
stmt.addBatch("INSERT INTO COFFEES " +
                "VALUES('Hazelnut', 49, 9.99, 0, 0)");
stmt.addBatch("INSERT INTO COFFEES " +
                "VALUES('Amaretto_decaf', 49,
                10.99, 0, 0)");
stmt.addBatch("INSERT INTO COFFEES " +
                "VALUES('Hazelnut_decaf', 49,
                10.99, 0, 0)");

int [] updateCounts = stmt.executeBatch();
con.commit();
con.setAutoCommit(true);
=====================================



***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:44)
Posted by 아름프로
결과 비교 :
================================================
res1  : 0.791초
res2  : 2.654초
res_full  : 3.646초
jacksun1001 : i love you1001 : 2002 : musician1100 : musician1100
.... 생략
jacksun1100 : i love you1100 : 2002 : musician1110 : musician1110
res3  : 0.04초
----------------------------------------------------------------------------------------
res1  : 0.791초
res2  : 0.1초
res_full  : 1.082초
jacksun1001 : i love you1001 : 2002 : musician1100 : musician1100
.... 생략
jacksun1100 : i love you1100 : 2002 : musician1110 : musician1110
res3  : 0.04초
=================================================

결론 :
결과적으로 2초 이상의 쿼리상의 이득을 얻을 수 있었습니다.
쿼리를 효율적으로 사용하기 어려운 상황이라면 이와 같이...
특정 범위에서 뽑아내는 방법에서 아이디어를 얻어서 설계하시면
퍼포먼스에 도움이 될겁니다.

ps :
더 좋은 방법을 JDBC2.0API에서 사용도 할 수 있겠지만,
MySQL의 최신 JDBC드라이버의 경우 아직 2.0이상의 새로운 메소드에
대해서 완전히 구현되지 않은 상황이라 absolute만 사용했습니다.




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:44)
Posted by 아름프로
(3), (4)에서는...
absolute를 이용하여 특정 위치를 결과를 뽑아서 사용할 경우의 속도 비교입니다.
5만건의 데이터를 쿼리한 것에서... 1001번째부터 1100까지 100개의 값을
추출하는 소스 입니다.

=============================================
while에서 뽑아오는 소스
--------------------------------------------------------------------------------

import java.sql.*;
import java.util.Vector;

public class DBTest6 {
        
        Vector result = new Vector();
        
        public void init() {
                
                long start_full = System.currentTimeMillis();
                
                String musician, music_subject, music_year, music_write, music_compose = null;
                Connection conn = null;
                Statement stmt = null;
                
                try {
                        Class.forName("org.gjt.mm.mysql.Driver");
                }catch (ClassNotFoundException ex) {
                        System.err.println("ClassNotFoundException: " + ex.getMessage());
                }

                try{
                        conn = DriverManager.getConnection("jdbc:mysql://localhost/music","music","music");

                        if(conn != null)  {
                                stmt = conn.createStatement();
                                
                                long start = System.currentTimeMillis();

                                ResultSet rst = stmt.executeQuery("select musician, music_subject, music_year, music_write, music_compose from musictest");                                
                                
                                long end = System.currentTimeMillis();
                                double res1 = (double)(end - start) / 1000;
                                //System.out.println("start1 : "+start);
                                //System.out.println("end2  : "+end);
                                System.out.println("res1  : "+res1+"초");
                                
                                long start2 = System.currentTimeMillis();
                                                                                                
                                while(rst.next()) {
                                        musician = rst.getString(1);
                                        music_subject = rst.getString(2);
                                        music_year = rst.getString(3);
                                        music_write = rst.getString(4);
                                        music_compose = rst.getString(4);
                                        
                                        Vector row = new Vector();
                                        row.add(musician);
                                        row.add(music_subject);
                                        row.add(music_year);
                                        row.add(music_write);
                                        row.add(music_compose);
                                        result.add(row);
                                }
                                
                                conn.close();
                                long end2 = System.currentTimeMillis();
                                double res2 = (double)(end2 - start2) / 1000;
                                
                                System.out.println("res2  : "+res2+"초");
                        }
                }catch(Exception e) {
                          e.printStackTrace();
                }finally {
                        if ( stmt != null ) try{stmt.close();}catch(Exception e){}
                        if ( conn != null ) try{conn.close();}catch(Exception e){}
                  }
                
                long end_full = System.currentTimeMillis();
                double res_full = (double)(end_full - start_full) / 1000;
                System.out.println("res_full  : "+res_full+"초");
        }
        
        public Vector getResult(){                
                return result;        
        }                
        
        public static void main(String[] args) {
                
                DBTest6 db = new DBTest6();
                db.init();
                Vector result = db.getResult();
                
                long start = System.currentTimeMillis();
                for(int i=1000; i < 1100; i++){
                        Vector row = (Vector)result.get(i);
                        
                        String musician = (String)row.get(0);
                        String music_subject = (String)row.get(1);
                        String music_year = (String)row.get(2);
                        String music_write = (String)row.get(3);
                        String music_compose = (String)row.get(4);
                        
                        System.out.println(musician +" : "+ music_subject + " : "+ music_year + " : "+ music_write + " : "+music_compose);                                                
                }
                long end = System.currentTimeMillis();
                double res2 = (double)(end - start) / 1000;
                System.out.println("res3  : "+res2+"초");
        }
}

---------------------------------------------------------------------------
absolute를 써서 뽑아오는 경우
---------------------------------------------------------------------------

import java.sql.*;
import java.util.Vector;

public class DBTest5 {
        
        Vector result = new Vector();
        
        public void init() {
                
                long start_full = System.currentTimeMillis();
                
                String musician, music_subject, music_year, music_write, music_compose = null;
                Connection conn = null;
                Statement stmt = null;
                
                try {
                        Class.forName("org.gjt.mm.mysql.Driver");
                }catch (ClassNotFoundException ex) {
                        System.err.println("ClassNotFoundException: " + ex.getMessage());
                }

                try{
                        conn = DriverManager.getConnection("jdbc:mysql://localhost/music","music","music");

                        if(conn != null)  {
                                stmt = conn.createStatement();
                                
                                long start = System.currentTimeMillis();

                                ResultSet rst = stmt.executeQuery("select musician, music_subject, music_year, music_write, music_compose from musictest");                                
                                
                                long end = System.currentTimeMillis();
                                double res1 = (double)(end - start) / 1000;
                                System.out.println("res1  : "+res1+"초");
                                
                                long start2 = System.currentTimeMillis();
                                                                                                                
                                int j = 1001;
                                rst.absolute(j);
                                for(int i = 0 ; i < 100 ; i++){
                                        musician = rst.getString(1);
                                        music_subject = rst.getString(2);
                                        music_year = rst.getString(3);
                                        music_write = rst.getString(4);
                                        music_compose = rst.getString(4);
                                        
                                        Vector row = new Vector();
                                        row.add(musician);
                                        row.add(music_subject);
                                        row.add(music_year);
                                        row.add(music_write);
                                        row.add(music_compose);
                                        result.add(row);
                                        
                                        rst.next();
                                }                                
                                
                                conn.close();
                                long end2 = System.currentTimeMillis();
                                double res2 = (double)(end2 - start2) / 1000;
                                
                                System.out.println("res2  : "+res2+"초");                                
                        }
                }catch(Exception e) {
                          e.printStackTrace();
                }finally {
                        if ( stmt != null ) try{stmt.close();}catch(Exception e){}
                        if ( conn != null ) try{conn.close();}catch(Exception e){}
                }

                
                long end_full = System.currentTimeMillis();
                double res_full = (double)(end_full - start_full) / 1000;
                System.out.println("res_full  : "+res_full+"초");
        }
        
        public Vector getResult(){                
                return result;        
        }                
        
        public static void main(String[] args) {
                
                DBTest5 db = new DBTest5();
                db.init();
                Vector result = db.getResult();
                
                long start = System.currentTimeMillis();
                for(int i=0; i < result.size(); i++){
                        Vector row = (Vector)result.get(i);
                        
                        String musician = (String)row.get(0);
                        String music_subject = (String)row.get(1);
                        String music_year = (String)row.get(2);
                        String music_write = (String)row.get(3);
                        String music_compose = (String)row.get(4);
                        
                        System.out.println(musician +" : "+ music_subject + " : "+ music_year + " : "+ music_write + " : "+music_compose);                                                
                }
                long end = System.currentTimeMillis();
                double res2 = (double)(end - start) / 1000;
                System.out.println("res3  : "+res2+"초");
        }
}
=============================================
결과는 (4)에서.. 계속..




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:44)
Posted by 아름프로
Select 테스트 5만건

결과
============================
1차 :
----------------------------------
res1  : 0.651초
res2  : 2.303초
res_full  : 3.134초
res3  : 0.02초
============================
2차 :
----------------------------------
res1  : 0.671초
res2  : 2.333초
res_full  : 3.174초
res3  : 0.021초
============================
3차 :
----------------------------------
res1  : 0.651초
res2  : 2.324초
res_full  : 3.155초
res3  : 0.03초
============================

결론
1. 가장 많은 시간을 차지하는 부분 while 문을 써서 데이터 추출하는 부분(res2)
2. 두번째로 많이 시간 걸리는 부분 (res1)
3. 5만건의 2차원 Vector로 결과치 처리하는데는 미미한(!) 시간 소요
4. MySQL5만건 기준시 데이터처리시에만 3초 정도소요
    (가장 기본적인 Query와 결과치를 뽑아내는 방식일 경우)

해결방안
1. Query 사용시 조건문의 절적한 사용
2. while 문을 통해 전체를 뽑는 방식보다는 ResultSet에서
    화면단위의 특정 부분을 뽑아서 결과를 만드는 방식 활용
    (absolute 등의 메소드 적절히 활용)
3. 1의 방식은 특정 DB에 종속되는 Query로만 해결가능 하므로 약간의 DB종속적인
    Query가 됨. (DB에 종속되지 않는 솔루션 만들시에는 검토대상)
4. 화면단위의 처리가 있는 경우 더 많은 시간 소요
5. 네트워크를 넘어 결과의 Object로 처리시 더 많은 시간 소요

해결방안으로 제시한 내용은 다음 글에서 계속... (작성하게 되면.. ㅡㅡ;; )




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:44)
Posted by 아름프로
테스트 사양
P-4 : 1.6
RAM : 512
DB : MySQL 3.23.25 for window
OS : Windows2000 Server
============================================
간단한 insert 소스
----------------------------------------------------

import java.sql.*;

/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/

public class DBTest4 {
        String name = null;
        String title = null;
        String track = null;

        public void init() {
                Connection conn = null;
                PreparedStatement stmt = null;
                
                try {
                        Class.forName("org.gjt.mm.mysql.Driver");
                }catch (ClassNotFoundException ex) {
                        System.err.println("ClassNotFoundException: " + ex.getMessage());
                }

                try{
                        
                        String sql = "insert into musictest values(?, ?, ?, ?, ?)";
                        conn = DriverManager.getConnection("jdbc:mysql://localhost/music","music","music");
                        
                        for(int i=1; i <= 50000; i++){
                                stmt = conn.prepareStatement(sql);
                                stmt.setString(1, "jacksun"+i);
                                stmt.setString(2, "i love you"+i);
                                stmt.setString(3, "2002");
                                stmt.setString(4, "musician1"+i);
                                stmt.setString(5, "musician2"+i);
                                stmt.executeUpdate();
                                System.out.println("count : "+i);
                        }
                                                                
                        conn.close();
                }catch(Exception e) {
                          e.printStackTrace();
                }finally {
                        if ( stmt != null ) try{stmt.close();}catch(Exception e){}
                        if ( conn != null ) try{conn.close();}catch(Exception e){}
                }
        }

        public static void main(String[] args) {
                DBTest4 db = new DBTest4();
                db.init();
        }
}

==============================================
select 소스
----------------------------------------------------


import java.sql.*;
import java.util.Vector;

/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/

public class DBTest2 {
        
        Vector result = new Vector();
        
        public void init() {
                
                long start_full = System.currentTimeMillis();
                
                String musician, music_subject, music_year, music_write, music_compose = null;
                Connection conn = null;
                Statement stmt = null;
                
                try {
                        Class.forName("org.gjt.mm.mysql.Driver");
                }catch (ClassNotFoundException ex) {
                        System.err.println("ClassNotFoundException: " + ex.getMessage());
                }

                try{
                        conn = DriverManager.getConnection("jdbc:mysql://localhost/music","music","music");

                        if(conn != null)  {
                                stmt = conn.createStatement();
                                
                                long start = System.currentTimeMillis();

                                ResultSet rst = stmt.executeQuery("select musician, music_subject, music_year, music_write, music_compose from musictest");                                
                                
                                long end = System.currentTimeMillis();
                                double res1 = (double)(end - start) / 1000;
                                //System.out.println("start1 : "+start);
                                //System.out.println("end2  : "+end);
                                System.out.println("res1  : "+res1+"초");
                                
                                long start2 = System.currentTimeMillis();
                                
                                while(rst.next()) {
                                        musician = rst.getString(1);
                                        music_subject = rst.getString(2);
                                        music_year = rst.getString(3);
                                        music_write = rst.getString(4);
                                        music_compose = rst.getString(4);
                                        
                                        Vector row = new Vector();
                                        row.add(musician);
                                        row.add(music_subject);
                                        row.add(music_year);
                                        row.add(music_write);
                                        row.add(music_compose);
                                        result.add(row);
                                }
                                conn.close();
                                long end2 = System.currentTimeMillis();
                                double res2 = (double)(end2 - start2) / 1000;
                                
                                //System.out.println("start1 : "+start2);
                                //System.out.println("end2  : "+end2);
                                System.out.println("res2  : "+res2+"초");                                
                        }
                }catch(Exception e) {
                          e.printStackTrace();
                }finally {
                        if ( stmt != null ) try{stmt.close();}catch(Exception e){}
                        if ( conn != null ) try{conn.close();}catch(Exception e){}
                  }

                
                long end_full = System.currentTimeMillis();
                double res_full = (double)(end_full - start_full) / 1000;
                System.out.println("res_full  : "+res_full+"초");
        }
        
        public Vector getResult(){                
                return result;        
        }                
        
        public static void main(String[] args) {
                
                DBTest2 db = new DBTest2();
                db.init();
                Vector result = db.getResult();
                
                long start = System.currentTimeMillis();
                for(int i=0; i < result.size(); i++){
                        Vector row = (Vector)result.get(i);
                        
                        String musician = (String)row.get(0);
                        String music_subject = (String)row.get(1);
                        String music_year = (String)row.get(2);
                        String music_write = (String)row.get(3);
                        String music_compose = (String)row.get(4);
                                                
                }
                long end = System.currentTimeMillis();
                double res2 = (double)(end - start) / 1000;
                //System.out.println("start2 : "+start);
                //System.out.println("end2  : "+end);
                System.out.println("res3  : "+res2+"초");
        }
}

=======================================

결과는 이어서 계속 ...




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:44)
Posted by 아름프로
자바서비스넷에 있는 내용인데 링크해봅니다.
매번 하면서 고민하는 것인데... 그럴때마다 매번 다시 읽어보고 하는데..
그럴때마다.. 다시 찾고하는데 시간걸리고.. ㅡㅡ;;
저같은 고생들 하지 마시라고 링크해봅니다.



***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:44)
Posted by 아름프로

BLOG main image

카테고리

분류 전체보기 (539)
이야기방 (19)
토론/정보/사설 (16)
IBM Rational (9)
U-IT (0)
SOA/WS/ebXML (110)
개발방법론/모델링 (122)
J2SE (34)
J2EE (60)
JDO (7)
JSP (2)
Java XML (5)
Java Mail (0)
JSF (1)
JMS (10)
Servlet (0)
Security (0)
Transactions (0)
Connector Arch (0)
WAS (8)
개발툴 (4)
JSTL (0)
Interoperability (1)
docs (6)
RMI (1)
JBI (2)
Rules Engine (1)
EJB (5)
JDBC (7)
DataBase (39)
Open Projects (30)
BP/표준화 (50)
Apache Projects (15)
Web/보안/OS (22)
Tools (7)
AJAX/WEB2.0 (1)
Linux/Unix (1)
영어 (0)
비공개방 (0)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

달력

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

글 보관함

Total :
Today : Yesterday :