8. 애플리케이션 커서 캐싱
2010.06.29 14:11
세션커서캐싱을 이용 하면 SGA이 공유 커서를 빠르게 찾아서 커서를 오픈 할 수 있다.
그렇다하더라도, 공유 커서 힙을 Pin 하고 실행에 필요한 메모리 공간을 PGA에 할당하는 등의 작업은 반복하게 한다.
애플리케이션 커서 캐싱을 이용하여 이 과정마저 생략하는 것이 가능하다.
- 패턴① : 바인드 변수를 사용하지 않을 때.
- 패턴② : 바인드 변수를 사용, 커서캐싱을 하지 않을 때.
- 패턴③ : 커서를 닫지 않고 재사용할 때.
- 패턴④ : 묵시적 캐싱 기능을 사용할 때.
각각의 패턴을 Java를 예로 살펴 보자.
패턴① 바인드 변수를 사용하지 않을 때.
/**
* 패턴1.
*/
public static void noBinding(Connection conn) throws Exception {
PreparedStatement stmt = null;
ResultSet rs = null;
String sql = null;
for (int i = 1 ; i <= 5000; i++ ) {
sql = "SELECT /* no_biding */ " + i + "," + i + ",'test',a.* FROM scott.emp a WHERE a.ename LIKE 'W%'";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
rs.close();
stmt.close();
}
}
위 소스를 보면 SQL문이 계속 변하는 것을 알 수 있다.
select /* no_binding */ 1,1,'test',a.* FROM scott.emp a WHERE a.ename LIKE 'W%'
select /* no_binding */ 2,2,'test',a.* FROM scott.emp a WHERE a.ename LIKE 'W%'
select /* no_binding */ 3,3,'test',a.* FROM scott.emp a WHERE a.ename LIKE 'W%'
.
.
.
select /* no_binding */ 5000,5000,'test',a.* FROM scott.emp a WHERE a.ename LIKE 'W%'
즉, 하드파싱이 대입값만큼 발생 (1~5000)
패턴② 바인드 변수를 사용、커서캐싱을 하지않을때.
/**
* 패턴2.
*/
public static void noCaching(Connection conn) throws Exception {
PreparedStatement stmt = null;
ResultSet rs = null;
String sql = null;
for (int i = 1 ; i <= 5000; i++ ) {
sql = "SELECT /* no_biding */ ?,?,?,a.* FROM scott.emp a WHERE a.ename LIKE 'W%'";
stmt = conn.prepareStatement(sql);stmt.setInt(1, i);
stmt.setInt(2, i);
stmt.setString(3, "test");
rs = stmt.executeQuery();rs.close();
stmt.close(); // 커서를 닫음.
}
}
위 소스를 보면 SQL문은 한개로 해결. 바인드값만이 변함.
select /* no_binding */ ?,?,?,a.* FROM scott.emp a WHERE a.ename LIKE 'W%'
즉, 하드파싱이 한번만 일어난다.
그러나, 루프내에서 커서를 닫아, 항상 커서를 생성하게 된다.
- Parse Count : 5000
- Execute Count : 5000
- Fetch Count : 5000
패턴③ 커서를 닫지 않고 재사용할 경우.
/**
* 패턴3.
*/
public static void cursorHolding(Connection conn) throws Exception {
PreparedStatement stmt = null;
String sql = "SELECT /* no_biding */ ?,?,?,a.* FROM scott.emp a WHERE a.ename LIKE 'W%'";stmt = conn.prepareStatement(sql);
ResultSet rs = null;
for (int i = 1 ; i <= 5000; i++ ) {
stmt.setInt(1, i);stmt.setInt(2, i);
stmt.setString(3, "test");
rs = stmt.executeQuery();rs.close();
}
stmt.close(); // 루프가 끝나면 커서를 닫는다.}
위 소스를 보면 SQL문은 한개로 해결. 바인드값만이 변함.
select /* no_binding */ ?,?,?,a.* FROM scott.emp a WHERE a.ename LIKE 'W%'
즉, 하드파싱이 한번만 일어난다.
또한, 커서를 루프가 종료후에 닫고 있다. 이것을 애플리케이션 커서 라 한다.
- Parse Count : 1
- Execute Count : 5000
- Fetch Count : 5000
패턴④ 묵시적 캐싱을 사용할 경우.
/**
// 캐시 사이즈를 1로 지정
* 패턴4.
*/
public static void cursorCaching(Connection conn) throws Exception {((OracleConnection) conn).setStatementCacheSize(1);
// 묵시적 캐싱 기능을 활성화
((OracleConnection) conn).setImplicitCachingEnabled(true);
PreparedStatement stmt = null;
ResultSet rs = null;
for (int i = 1 ; i <= 5000; i++ ) {
String sql = "SELECT /* no_biding */ ?,?,?,a.* FROM scott.emp a WHERE a.ename LIKE 'W%'";stmt = conn.prepareStatement(sql);
stmt.setInt(1, i);
stmt.setInt(2, i);
stmt.setString(3, "test");
rs = stmt.executeQuery();
rs.close();
stmt.close(); // 루프가 끝나면 커서를 닫는다. 그러나, 내부적으로는 닫지않고 캐시에 보관
}
}
위 소스를 보면 패턴②와 같은 형태를 하면서도 사실상 패턴③과 같은 성능을 보인다.
즉, JDBC의 API에서 제공하는 기능을 이용하여 매번 커서를 닫는듯한 코딩을 해도 내부적으로는 세션커서캐싱을 한다.- Parse Count : 1
- Execute Count : 5000
- Fetch Count : 5000
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
27 | 9. ASH(Active Session History) | 실천하자 | 2010.06.14 | 15607 |
26 | 8. Statspack / AWR | balto | 2010.06.13 | 12767 |
25 | 7. Response Time Analysis 방법론과 OWI | balto | 2010.06.13 | 8066 |
24 | 5. 오라클 Lock | 휘휘 | 2010.06.07 | 26368 |
23 | 4. 동시성 구현 사례 | 토시리 | 2010.06.07 | 10939 |
22 | 3. 비관적 vs. 낙관적 동시성 제어 | 휘휘 | 2010.06.07 | 8210 |
21 | 2. 트랜잭션 수준 읽기 일관성 | 휘휘 | 2010.06.07 | 19568 |
20 | 4. DBMS_XPLAN 패키지 | balto | 2010.06.06 | 10461 |
19 | 3. SQL 트레이스 | balto | 2010.06.06 | 21175 |
18 | 3장. 오라클 성능 관리 | 운영자 | 2010.06.06 | 6697 |
17 | 2. AutoTrace | 실천하자 | 2010.06.06 | 8597 |
16 | 1. Explain Plan | 실천하자 | 2010.06.06 | 14663 |
15 | 2장. 트랜잭션과 Lock | 운영자 | 2010.06.01 | 6895 |
14 | 6. 문장수준 읽기 일관성 | 토시리 | 2010.06.01 | 10432 |
13 | 1. 트랜잭션 동시성 제어 | 실천하자 | 2010.05.31 | 8631 |
12 | 5. Undo | 토시리 | 2010.05.31 | 18653 |
11 | 11. Shared Pool | 실천하자 | 2010.05.31 | 18511 |
10 | 8. 블록 클린아웃 | 휘휘 | 2010.05.31 | 12283 |
9 | 7. Consistent vs. Current 모드 읽기 | 휘휘 | 2010.05.31 | 10537 |
8 | 10. 대기 이벤트 | balto | 2010.05.30 | 8011 |