대메뉴 바로가기 본문 바로가기

데이터 기술 자료

데이터 기술 자료 상세보기
제목 All about JDBC Performance Tuning
등록일 조회수 8424
첨부파일  

All about JDBC Performance Tuning

㈜엑셈 컨설팅본부 /APM팀 임 대호



개요

JDBC 란 Java Database Connectivity 의 약어이며 , 데이터베이스 표준 접근 API(Application Programing Interface) 를 말한다 . JDBC 를 사용하면 어떤 관계 형 데이터베이스에서도 , 각 데 이터베이스에 맞는 접근 프로그램을 따로 생성할 필요 없이 사용할 수 있다 . 이 JDBC 는 WAS (Web Appl ication Server) 와 DB Server (Database Server) 사이에서의 연결을 담당하는 중 요한 역할을 수행하고 있다 . WAS 에서 SQL 을 제대로 보내고 DB 에서 수행결과를 빠르게 리턴 한다고 해도 , JDBC 에 문제가 있다고 하면 성능문제를 야기할 수 있다 . 앞으로 JDBC 로 인해 발 생할 수 있는 성능 문제가 무엇인지 살펴보고 좀 더 나은 Performance 를 내기 위한 방법이 어 떤 것이 있는지 알아 볼 것이다 .


JDBC 구조

JDBC 는 크게 JDBC API, JDBC Manager, JDBC Driver API 로 구성되어 있다 .


JDBC 역할

우선 간단히 JDBC 의 역할에 대해서 알아보자 .


Application 에서 Parameter 값을 받아 JDBC Interface 로 보내게 되면 적절한 JDBC Driver 를 통해 SQL 을 Database 로 보내주게 되고 결과를 받아서 사용자에게 보여주게 된 다 .


JDBC Interface

JDBC 의 핵심 Interface 는 Connection, Statement, ResultSet 인데 간단히 살펴보도록 하자 .


JDBC Interface 를 사용하려면 java.sql, javax.sql Package 를 사용해야 하는데 java.sql Package 은 DBMS 에 저장된 정보를 다루기 위해 사용되고 , javax.sql Package 는 Datasource 로 접근하기 위해 사용된다 . 핵심 인터페이스인 Connection, Statement, ResultSet 을 사용하려면 java.sql Package 를 Import 해주면 된다 .


JD BC Interface 의 사용

핵심 Interface 가 어떤 일련의 과정으로 사용되는지 살펴보도록 하자 . Driver Manager 를 사용 할 때를 예로 들겠다 . 일단 JDBC Driver Manager 를 통해서 적합한 Driver 를 로딩하게 된 다 .(JDBC Driver 는 JDBC Call 을 DBMS 에 전달하고 Result 를 받아서 JDBC Interface 에 넘 겨주는 역할을 한다 ) Driver 가 로딩되면 Connection 객체를 생성한다 . 그런 다음 획 득한 Connection 객체로부터 Statement 객체를 획득하고 SQL 을 수행한다 . S elect 의 경우는 Resultset 이 있으므로 결과를 가져오기 위해 ResultSet 객체를 생성한다 .

[code 1]

앞으로 사용될 Driver 는 Oracle 을 기준으로 하겠다 .

위의 코드를 간단하게 살펴보자 5 번째 줄을 보면 Oracle 의 경우 Driver 클래스 명이 oracle.jdbc.driver.OracleDriver 인 것을 알 수 있다 . 6 번째 줄은 Driver 가 로딩이 되면 Driver Manager 클래스의 getConnection(url,user,password) Method 를 이용해서 Connection 객체를 생성하는 것을 알 수 있다 . Oracle 의 경우 Url 은 jdbc:oracle:thin:@ip:port:SID 형식이다 . 8 번째 줄을 보면 Select 를 사용했으므로 ResultSet Interface 가 사용되었다 . 10~12 번째 줄 을 보면 close() 처리를 해줬다 . 이는 모든 java.sql 관련된 Resource 는 사용하면 반드시 반납 을 해줘야 하기 때문이다 .

만약 반납하지 않는다면 모든 Connection 을 다 사용 하게 되어서 Thread pool 이 밀리는 현상 이 발생하고 최악의 경우는 WAS Crash 현상이 나타날 수 있다 . 지금까지 간단히 JDBC 의 구조 를 알아보았다 . 이제 JDBC 로 인해 발생할 수 있는 성능문제에 대해서 살펴보도록 하자 .


JDBC 성능문제

JDBC 로 인해 다양한 성능문제가 발생할 수 있다 어떤 성능문제 발생하는지 살펴보도록 하자 .


JDBC Driver Type

JDBC Driver 는 4 가지의 종류가 있다 .


간단히 각 Driver 에 대해서 살펴보자 . Type1 인 JDBC - ODBC Bridge Driver 는 JDBC 를 사용 해서 , ODBC 데이터소스에 접근하는 방식으로 제한이 많고 비효율적이다 . Type2 인 Native API Driver 는 Java + JNI 방식으로 Native Call 하는 부분이 추가된다 . Type3 인 Net - Protocol Driver 는 Net protocol 을 사용하여 Mi ddleware 계층 서버와 통신하는 방식이다 . Type4 인 Native - Protocol Driver 는 Pure java 방식이고 TCP/IP 로 S ocket 을 이용하는 방식이다

Type1 방식은 플랫폼에 종속적이고 JDBC 의 요청을 ODBC 로 , ODBC 에서의 응답을 JDBC 로 변경해주는 과정 때문에 불필요한 Overhead 가 발생하게 된다 . Type2 방식은 Native Code 로 되어 있는 Database Library 를 설치해줘야 한다 . Type3 방 식은 Application 과 DBMS 사이에 Middleware 를 구현하고 JDBC Driver 는 Middleware 에 요청하는 방식인데 Middle Tier 가 추 가되기 때문에 Bottleneck 현상의 원인이 될 수 있다 . Type4 방식은 Socket 통신을 하기 때문 에 Socket 통신에 소비되는 시간을 고려해야만 한다 . 이와 같이 4 가지의 Driver Type 이 있다 .


DriverManager

Connection 객체를 생성하고 제거하는 작 업은 상당히 고비용의 작업이다 . 달리 말하자면 DriverManager 의 getConnection() Method 를 이용해서 Connection 객체를 얻어내는 것이 고비용의 작업이란 이야기이다 . Connection 이 비록 Idle 한 상태에 있는다 하더라도 생성 및 제거 작업을 하는 것 보다 차라리 Open 해 놓은 상태로 있는 것이 훨씬 유리하다 . Mark Chamness 의 Performance Tuning For the JDBC API 문서에 따르면 C onnection 을 생성하고 제거하는 작업이 평균 0.5 초에서 2 초 사이가 걸린다고 한다 만약 반복적인 Open 과 Close 가 발생한다면 Application 성능 저하가 나 타날 것이다 . Connection 관리를 효율적으로 하기 위해서는 Connection Pool 을 사용하면 된다 ..


Statement

Statement 객체는 주로 간단한 SQL 을 전송할 때 쓰인다 . 하지만 Statement 객체는 다음과 같은 데이터처리의 한계를 가진다 .

1. 반복 되는 똑 같은 질의도 새로운 질의로 해석된다 .
2. 질의 조건이 달라질 때 마다 하드코딩 해야 한다 .

이와 같이 Statement 가 갖는 한계점은 Prepared Statement 를 사용하면 해결할 수 있다 .


Transaction Isolation Level

Transaction Isolation Level 은 다음과 같이 4 가지로 나뉘게 된다 .


트랜잭션 고립화의 수준을 높일수록 데이터의 일관성은 향상되지만 , 확장된 Lock 을 사용하게 되므로 동시성이 저하가 된다 . ( 단 Oracle 은 Lock 이 아닌 Undo 메카니즘을 사용한다 )


SQL

SQL 은 WAS 와 DB 성능에 직결된다 하드웨어의 Spec 을 아무리 뛰어나게 구성한다고 해도 업 무성격을 잘못 이해하 고 SQL 을 작성하거나 (Outer Join) 비효율적으로 작성하게 (Subquery 남용 ) 되면 성능 저하 및 장애를 유발할 수 있다 . 또한 과도한 Fetch Count 는 Out Of Memory Error 를 유발하고 WAS Crash 를 유발하기도 한다 .


JDBC 성능문제 해결

이전에 살펴보았듯이 JDBC 성능문제는 여러 원인과 연관되어 있다 . 이제 JDBC 성능문제를 해 결하는 방법에 대해서 알아보도록 하자 .


Connection Pool 사용

Connection Pool 을 사용하게 되면 Connection 객체를 생성하고 제거하는 작업을 하지 않아도 되기 때문에 Overhead 가 적고 응답속도가 빠르게 된다 . 또한 Connection 의 수의 제한을 두기 때문에 연결관리에 효율적이다 . 그리고 JNDI Look Up 을 하여 접근할 수 있으므로 특정한 드라 이버나 속성에 구애 받지 않고 참조가 가능하다 .

Connection Pool 을 사용할 때 주의해야 할 사항이 있는데 그것은 적절한 Pool Size 에 대해 고 려해야만 한다는 것이다 . 이는 Pool Size 와 Performance 가 Trade Off 의 관계에 있기 때문이 다 . 적절한 Pool Size 설정을 위해서는 실제 Connection 사용량 및 OS Resource 사용량을 체 크하고 부하 Test 를 거쳐야 한다 .

Connection Pool 의 동작 방식은 다음과 같다 . 만약 WAS 에서 제공하는 Connection Pool 을 사용하게 된다면 Minimum 과 Maximum Size 를 설정할 수 있다 . 최초 Pool 을 생성시 Connection 을 Minimum Size 만큼 생성하게 되고 추가로 요청이 발생하면 Maximum Size 까 지 생성한다 . 그리고 사용이 없게 되면 다시 Minimum Size 까지 작아지게 된다 . 만약 Connection 생성 Delay 로 인한 이슈가 있다면 Minimum 과 Maximum Size 를 같게 설정하도 록 한다 .

주의 해야 할 점은 Connection 객 체를 close() 해주지 않으면 다른 사용자가 사용할 수 없으므로 반드시 close() 처리를 해주도록 한다 .

Transaction Isolation Level 사용

동시성 제어가 어려운 이유는 동시성과 일관성이 Trade Off 의 관계에 있기 때문이다 . Transaction Isolation Level 에 따라 다음의 문제점이 발생할 수 있다 .


업무 성격에 비해 Transaction Isolation Level 을 높게 사용할 경우 불필요하게 Transaction 의 동시성을 제한하게 되고 반대로 낮게 사용하게 되면 데이터의 무결성이 보장되지 않 을 수 있다 . 그러므로 업무성격에 맞는 Transaction Isolation Level 을 설정하는 것이 중요하다 .


Prepared Statement, Callable Statement 사용

SQL 문장을 반복적으로 DB 에 전송할 필요가 있다면 Prepared Statement 객체를 사용하도록 한다 . Prepared Statement 장점은 두 가지가 있다 첫째는 반복적으로 실행해야 하는 SQL 을 미리 컴파일 해서 저장해 놓음으로 실 행속도를 빠르게 할 수 있다 . 둘째는 Parameter 로 값을 넘길 수 있기 때문에 Hard Coding 할 필요가 없고 쉽게 인자를 전달하여 수행속도를 향상 시킬 수 있다 .

Callable Statement 는 DB 에서 미리 컴파일 된 Stored Procedure 을 실행하기 위해 사용한다 . 앞서 말한 Prepared Statement 와 Callable Statement 를 사용하게 되면 Statement Caching 기능을 사용할 수 있다 .


Statem ent Caching 사용

Prepared Statement 또는 Callable Statement 를 Application 이나 EJB 에서 사용하게 되면 WAS 와 DB 에 상당한 오버헤드가 발생할 수 있다 . JDBC 3.0 이상에서는 Statement Caching 기능을 사용할 수 있는데 , Statement Caching 이란 Prepared Statement 와 Callable Statement 를 Caching 하여 재사용할 수 있는 기능이다 . 이는 DB 의 CPU 사용량을 줄일 수 있 을 뿐 아니라 성능 향상을 도모할 수 있다 . 자료를 찾다가 Weblogic 의 Statement Caching 에 관한 자료가 있어서 옮겨 적어 본다 . Weblogic 은 Statement Cache Algorithm 이 두 가지가 존재하는데 LRU 방식과 Fixed 방식이 있다 .

- LRU 방식
- 캐시가 가득 찰 때까지 Prepared Statement 와 Callable Statement 를 Caching 한다 . 모든 캐시가 가득 차게 되 면 가장 적게 사용된 Statement 를 밀어내고 새로운 Statement 를 저장한 다 .

- Fixed 방식
- Statement 를 캐시하고 사이즈가 가득 차게 되면 더 이상 Statement 를 Caching 하지 않는다 .
Statement Cache 기능을 사용하기 전에 각 Connection 마다의 Cache Size 를 고려해야만 한 다 . 그 이유는 대부분의 경우에 있어서 Open Statement 하나당 하나의 커서를 유지하기 때문 이다 . 만약 많은 S tate ment 를 Caching 한다면 DB 의 Open Cursor 의 제한을 초과할 수 이고 Connection 이 10 개 그리고 2 개의 WAS 가 Clustering 된 구조라면 DB 에서는 캐시를 위해 200 개 (10*10*2) 의 Cursor 가 Open 되게 된다 .
Statement Cache Size 를 0 으로 설정하게 되면 해당 기능은 꺼지게 된다 . C aching 된 Statement 는 DDL 이 수행되고 나면 재 수행에 실패하게 되는데 , 이는 Caching 된 Statement 는 명시한 데이터베이스 오브젝트를 참조하기 때문이다 . 이는 Oracle 에서는 Breakable Parse Lock 과 관계가 있다 . Cursor 가 참조하는 오브젝트에 DDL 이 수행되면 실행가능 LCO 가 무효 화 된다 .


JDBC Driver 의 적절한 사용

JDBC 드라이버 Type 에 대한 적적한 이해가 필요하고 때에 따라서는 Test 도 필요하게 될 것이 다 . 그 이유는 WAS 와 DB 의 구성 환경에 따라 Type 의 선택이 달라질 수 있기 때문이다 .

예를 들어 WAS 와 DB 가 같은 Machine 에 있는 경우를 생각해보자 . Type4 의 경우는 Socket 을 이용한 다고 했는데 불필요한 TCP/IP Socket 통신이 발생하게 된다 . 만약 이런 시간으로 인해 데이터 베이스에 직접 접근하는 시간이 오래 걸린다고 하면 Native Call 을 하는 Type2 보다 유리할게 없다 환경 ( 구성 , JVM) 에 따라서는 Type2 가 Typ e4 보다 성능 면에서 유리할 수 있다 .

최적의 성능을 위해서 DB Server 와 DB Client JDBC Driver 는 동일 / 최신 버전을 사용하도록 한다 .


SQL Tuning 의 최적화

SQL 을 어떻게 작성하느냐 또는 어떻게 처리하느냐에 따라서 성능은 극과 극의 상황을 보여줄 수 있다 . 이처럼 SQL 작성은 WAS 와 DB 성능에 직결된다고 볼 수 있는데 , 개발자 입장에서 어 떤 SQL Tuning 방법이 있는지 살펴보도록 하자 .

1. 한번에 한 행을 처 리하지 않고 다수 행을 처리하는 addBatch(), executeBatch() 를 사용 하도록 한다 .
2. 읽기 전용 혹은 Data Update 가 일어나지 않는 질의는 caching 을 고려한다 .
3. Statement 보다는 Prepared Statement 를 사용해라
4. 대량의 Data 조회 시 Paging 처리를 하도록 한다 .
5. 적절한 예외처리를 이용해 반드시 Connection leak 을 막아 주도록 한다 .
6. 복잡한 SQL 질의 문이나 여러 개의 DB 호출을 하나로 통 합하는 Stored 프로시저를 사용하라 .
7. 불필요한 Meta Data 호출은 피한다 .
8. Application 요구에 맞는 가장 낮은 수준의 Transaction 을 사용한다 .
9. Transaction 과부하가 우려된다면 Auto commit 모드를 사용하지 않도록 한다 .
10. S ELECT * FROM TABLE 과 같은 조회는 피하고 필요한 칼럼만 기술하도록 한다 .
11. Result Set 을 Network 로 넘어오기 전에 줄여서 Round Trip 을 적게 발생시키도록 한 다 .


Oracle JDBC Performance Extension

Oracle JDBC Driver 는 Round Trip 을 줄여 성능을 향상시키는 다음의 기능을 지원한다

- Row Prefetch
접근 가능성이 높은 블록을 Fetch 할 때 Client Buffer 에 저장하여 불필요한 Round Trip 을 줄 인다

- Update Batching
Update, Delete, Insert 문을 하나의 batch 로 수행한다
Update Batching 은 Prepared Statement 와 함께 사용시 유용하다
Oracle JDBC 의 Update Batching 방식에는 Standard Model 과 Oracle - Specific Model 이 있지만 두 모델을 함께 사용할 수는 없다


결론

Framework 가 개발의 대부분을 차지하고 있는 이시대 JDBC 의 성능에 대한 고찰은 시대에 뒤 떨어져 보일 수 있다 . 하지만 WAS 에서 수행한 Application 이 어떻게 DB 까지 전달되어서 결 과를 사용자에 게 보여주는지에 대한 궁금증은 어느 정도 해소가 되었으리라 본다 . 그 역할의 중 심에는 JDBC 가 있다 . 우리는 지금까지 JDBC 가 어떤 일을 수행하고 어떤 구조로 되어 있는지 또 어떤 문제를 일으키는지에 대해 알아보았다 . 어플리케이션 성능 관리가 주 업무인 나에게 JDBC 의 동작원리를 이해하는 것은 WAS DB 성능 전문가가 되기 위한 초석이 될 것이라고 생 각한다 .

JDBC 를 사용할 때 가장 큰 성능 개선을 할 수 있는 방법은 WAS 와 DB 사이에서의 Round Trip 을 적게 발생시키는 것이다 . Oracle Driver 는 이미 Round Trip 을 줄일 수 있는 Row Prefetch 나 Update Batching 기능을 제공하고 있다 . 하지만 이런 좋은 기능이 있음에도 불구하고 SQL 의 수행의 결과가 불필요하게 많은 ResultSet 을 가져온다면 심각한 성능 문제를 야기할 수 있 다 . 대표적으로 과도한 Fetch Count 로 인한 Out Of Memory Error 현상을 말할 수 있다 . 이를 해결 하기 위해서는 업무 성격을 잘 파악하여 Network 를 통해 넘어 오기 전에 ResultSet 을 줄 여 Round Trip 을 적게 발생시켜야 한다 ..

앞서 우리는 JDBC 의 핵심 Interface 에 대해서 살펴보았다 . 그렇다면 SQL 의 Parse 와 Execute 와 Fetch 는 어느 객체에서 수행이 될까 ? 답은 Java Performance Fundamental 에 나 오는데 S tatement 객체의 executeQuery() Method 단계에서 Parse, Execute, 1 회의 Fetch 가 수행된다고 한다 . 그리고 ResultSet 객체의 next() Method 에서 나머지 Fetch 가 수행된다 . Cursor 가 Open 되는 시점은 Parse 하는 시점과 동일하고 Close 되는 시점은 Connection 객체 가 Close 될 때이다 . 잘 이해가 되지 않는 다면 [code1] 을 참조하라

지금까지 JDBC 에 대해서 정리를 해보았다 . APM(Application Performance Management) 을 지원하 지만 큰 관점에서 보면 Database 역시 Application 의 한 부분이고 대부분의 성능 이슈 는 WAS 와 DB 상태를 같이 봐야 명확히 장애 원인이 밝혀지는 경우가 많다 . Oracle 에 대한 내 용을 추가한 것도 그런 맥락에서이다 .

기초를 단단히 잡고 싶은 마음에 JDBC 를 주제로 잡았다 . 뭐든지 가장 중요한 것은 기반을 튼튼 히 하는 것이라고 생각을 한다 . JDBC 지식을 기반으로 다음 백서의 주제는 Framework 가 될 것 같다


참고 문헌

서적
김 한도 , [Java Performance Fundamental]
Soluvill, [Enterprise Java JDBC]
문서 자료
Mark Chamness, [Performance Tuning For the JDBC API]
웹사이트
http://alumnus.caltech.edu/~chamness/JDBC_Tuning.pdf
http://etutorials.org/Programming/Java+performance+tuning/Chapter+16.+Tuning+J DBC/16.2+Tuning+JDBC/
http://docs.oracle.com/cd/E11035_01/wls100/jdbc/performance.html .



출처 : (주)엑셈

제공 : DB포탈사이트 DBguide.net