세션 커서, 애플리케이션 커서에 대해

xlwdn·2023년 8월 22일
0

공유 커서

SQL을 하드파싱한 결과를 저장하고 있는 오라클 객체이며 SGA에 저장된다. 공유 커서는 여러 세션 간에 공유될 수 있으며 단지 데이터를 저장하고 있을 뿐이다. 실제 SQL 실행을 위해선 PGA에 적재해야한다. 만약 라이브러리 캐시에 쿼리에 대한 공유 커서 존재 시 하드 파싱이 생략된다.

세션 커서

세션에서 쿼리를 실행하기 위해 공유 커서로부터 값을 읽어들인 값과 그 밖에 세션에 필요한 각종 상태 값을 저장하고 있는 오라클 객체이다. PGA에 존재하므로 다른 세션과 공유할 수 없으며 하나의 공유 커서에 여러 개의 세션 커서가 연결될 수 있고 서버나 세션 파라미터 설정 시 세션 커서를 사용하고 난 뒤에도 메모리에 캐싱해둘 수 있다.

만약 세션 커서가 캐싱되어 있다면 라이브러리 캐시에서 공유 커서를 탐색하지 않아도 되므로 라이브러리 캐시 래치를 획득하고 작업을 수행하는 과정이 생략된다.

애플리케이션 커서

애플리케이션 커서는 오라클 영역이 아닌 어플리케이션 영역이며 오라클에서 개발자를 위해 제공하는 세션 커서에 대한 인터페이스를 기반으로 생성한다.

애플리케이션 커서 이용 시 Parse Call을 획기적으로 줄일 수 있다.

Java code

각 예시는 아래 자바 코드를 통해 설명할 수 있다.

바인드 변수 미사용

public static void noBinding(Connection conn, int count)throws Exception{
		PreparedStatement stmt;
		ResultSet rs;
		Utils.sessionGetSPID(conn);
		Utils.sessionSetStart(conn);
		
		for(int i = 1; i <= count; i++){
			stmt = conn.prepareStatement(
				"SELECT /* no_binding */" + i + ", " + i + ", 'test', a.* " +
				"FROM emp a WHERE a.ename LIKE 'W%'");
			rs = stmt.executeQuery();
			
			rs.close();
			stmt.close();
		}
		Utils.sessionSetEnd(conn);
	}

바인드 변수를 사용하지 않은 예시이다. 또한 매 연결마다 stmt를 생성하고 끊는다.

public static void noCaching(Connection conn, int count)throws Exception{
		PreparedStatement stmt;
		ResultSet rs;
		Utils.sessionGetSPID(conn);
		Utils.sessionSetStart(conn);
		
		for(int i = 1; i <= count; i++){
			stmt = conn.prepareStatement(
				"SELECT /* no_caching */ ?, ?, ?, a.* " +
				"FROM emp a WHERE a.ename LIKE 'W%'");
			stmt.setInt(1, i);
			stmt.setInt(2, i);
			stmt.setString(3, "test");
			rs = stmt.executeQuery();
			
			rs.close();
			stmt.close();
		}

		Utils.sessionSetEnd(conn);
	}

바인드 변수를 사용한 예시이다.

public static void cursorHolding(Connection conn, int count)throws Exception{
		PreparedStatement stmt = conn.prepareStatement(
			"SELECT /* cursor_holding */ ?, ?, ?, a.* " +
			"FROM emp a WHERE a.ename LIKE 'W%'");
		ResultSet rs;
		
		Utils.sessionGetSPID(conn);
		Utils.sessionSetStart(conn);
		
		for(int i = 1; i <= count; i++){
			stmt.setInt(1, i);
			stmt.setInt(2, i);
			stmt.setString(3, "test");
			rs = stmt.executeQuery();
			
			rs.close();
		}
		stmt.close();
		
		Utils.sessionSetEnd(conn);
	}

바인드 변수를 사용하며 stmt를 for문 이후에 끊는다.

https://m.blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=salinokl&logNo=221453265426

http://wiki.gurubee.net/pages/viewpage.action?pageId=4948589

0개의 댓글