선택 버퍼링 사용

선택 버퍼링은 Microsoft SQL Server 2005 JDBC 드라이버 버전 1.2에 새로 도입된 기능으로 서버 커서 오버헤드 없이 모든 종류의 큰 값 데이터를 검색할 수 있도록 디자인되었습니다. 응용 프로그램은 드라이버가 지원하는 SQL Server의 모든 버전에서 선택 버퍼링 기능을 사용할 수 있습니다.

일반적으로 Microsoft SQL Server JDBC 드라이버는 쿼리를 실행할 때 모든 결과를 서버에서 검색하여 응용 프로그램 메모리에 넣습니다. 이 방법은 SQL Server에서 리소스 소비를 최소화하지만 매우 큰 결과를 생성하는 쿼리의 경우 JDBC 응용 프로그램에서 OutOfMemoryError가 발생할 수 있습니다.

응용 프로그램에서 매우 큰 결과를 처리할 수 있도록 하기 위해 Microsoft SQL Server JDBC 드라이버에서는 선택 버퍼링을 제공합니다. 선택 버퍼링을 사용하면 드라이버는 SQL Server에서 문 실행 결과를 한 번에 모두 검색하는 것이 아니라 응용 프로그램에 필요할 때 검색합니다. 또한 응용 프로그램에서 더 이상 액세스할 수 없는 결과를 즉시 삭제합니다. 다음은 선택 버퍼링을 유용하게 사용할 수 있는 몇 가지 예입니다.

  • 쿼리로 매우 큰 결과 집합이 생성되는 경우: 메모리에 저장할 수 있는 행보다 더 많은 행을 생성하는 SELECT 문을 응용 프로그램에서 실행하는 경우가 있습니다. 이전 릴리스에서는 OutOfMemoryError를 방지하기 위해 응용 프로그램에서 서버 커서를 사용해야 했습니다. 선택 버퍼링을 사용하면 서버 커서 없이도 임의의 큰 결과 집합을 정방향 읽기 전용으로 처리할 수 있습니다.

  • 쿼리로 매우 큰 SQLServerResultSet 열 또는 SQLServerCallableStatement OUT 매개 변수 값: 너무 커서 응용 프로그램 메모리에 저장할 수 없는 단일 값(열 또는 OUT 매개 변수)을 응용 프로그램에서 검색할 수 있습니다. 선택 버퍼링은 getAsciiStream, getBinaryStream, 또는 getCharacterStream 메서드를 사용하여 클라이언트 응용 프로그램에서 이러한 값을 스트림으로 검색할 수 있도록 합니다. 응용 프로그램은 스트림에서 읽으면서 SQL Server에서 해당 값을 검색합니다.

참고

선택 버퍼링을 사용하면 JDBC 드라이버는 필요한 양의 데이터만 버퍼링합니다. 드라이버는 버퍼 크기를 제어 또는 제한하는 공용 메서드를 제공하지 않습니다.

선택 버퍼링 설정

JDBC 드라이버 버전 2.0 이상에서 드라이버의 기본 동작은 "adaptive"입니다. 즉 선택 버퍼링을 사용하기 위해 응용 프로그램에서 명시적으로 선택 동작을 요청할 필요가 없습니다. 하지만 버전 1.2 릴리스에서는 버퍼링 모드가 기본적으로 "full"이므로 응용 프로그램에서 명시적으로 선택 버퍼링 모드를 요청해야 했습니다.

다음은 응용 프로그램에서 문 실행 시 선택 버퍼링을 사용하도록 요청할 수 있는 세 가지 방법입니다.

  • 응용 프로그램에서 연결 속성 responseBuffering을 "adaptive"로 설정할 수 있습니다. 연결 속성을 설정하는 방법은 연결 속성 설정을 참조하십시오.

  • 응용 프로그램에서 SQLServerDataSource 개체의 setResponseBuffering 메서드를 사용하여 해당 SQLServerDataSource 개체를 통해 생성된 모든 연결에 대해 응답 버퍼링 모드를 설정할 수 있습니다.

  • 응용 프로그램에서 SQLServerStatement 클래스의 setResponseBuffering 메서드를 사용하여 특정 문 개체에 대해 응답 버퍼링 모드를 설정할 수 있습니다.

JDBC 드라이버 버전 1.2를 사용하는 경우 응용 프로그램에서 setResponseBuffering 메서드를 사용하여 문 개체를 SQLServerStatement 클래스로 캐스팅해야 했습니다. 큰 데이터 읽기 샘플저장 프로시저로 큰 데이터 읽기 샘플의 코드 예에서는 이러한 이전 사용법을 보여 줍니다.

하지만 JDBC 드라이버 버전 2.0에서는 응용 프로그램에서 isWrapperFor 메서드 및 unwrap 메서드를 사용하여 구현 클래스의 계층 구조에 관계없이 공급업체별 기능에 액세스할 수 있습니다. 예제 코드를 보려면 큰 데이터 업데이트 샘플 항목을 참조하십시오.

선택 버퍼링을 사용하여 큰 데이터 검색

get<Type>Stream 메서드를 사용하여 큰 값을 한 번 읽은 다음 SQL Server에서 반환하는 순서로 ResultSet 열과 CallableStatement OUT 매개 변수에 액세스하면 결과를 처리할 때 선택 버퍼링이 응용 프로그램 메모리 사용량을 최소화합니다. 선택 버퍼링을 사용하면 다음과 같은 결과를 얻을 수 있습니다.

  • SQLServerResultSetSQLServerCallableStatement 클래스에 정의된 get<Type>Stream 메서드는 응용 프로그램에서 표시하는 경우 스트림을 재설정할 수 있다 하더라도 기본적으로 한 번 읽기 스트림을 반환합니다. 응용 프로그램에서 스트림 reset을 원할 경우 먼저 해당 스트림에서 mark 메서드를 호출해야 합니다.

  • SQLServerClobSQLServerBlob 클래스에 정의된 get<Type>Stream 메서드는 mark 메서드를 호출하지 않고 항상 스트림의 시작 위치로 변경될 수 있는 스트림을 반환합니다.

응용 프로그램에서 선택 버퍼링을 사용하는 경우 get<Type>Stream 메서드에 의해 검색된 값은 한 번만 검색될 수 있습니다. 같은 개체의 get<Type>Stream 메서드를 호출한 후 같은 열이나 매개 변수에서 get<Type> 메서드를 호출하려고 하면 "데이터에 액세스되었으나 이 열이나 매개 변수에는 사용할 수 없습니다."라는 메시지와 함께 예외가 발생합니다.

선택 버퍼링 사용에 대한 지침

응용 프로그램의 메모리 사용량을 최소화하기 위해 개발자들이 따라야 할 중요한 지침은 다음과 같습니다.

  • 응용 프로그램에서 매우 큰 결과 집합을 처리할 수 있도록 연결 문자열 속성 selectMethod=cursor를 사용하지 않도록 합니다. Microsoft SQL Server 2005 JDBC 드라이버 버전 1.2 이상에서는 선택 버퍼링 기능을 사용하여 응용 프로그램에서 서버 커서 없이 매우 큰 정방향 읽기 전용 결과 집합을 처리할 수 있습니다. selectMethod=cursor를 설정하면 해당 연결에서 생성한 모든 정방향 읽기 전용 결과 집합이 영향을 받습니다. 즉, 응용 프로그램에서 행 수가 적은 간단한 결과 집합을 자주 처리하는 경우 각 결과 집합에 대한 서버 커서를 만들고 읽고 닫는 작업을 할 때 selectMethodcursor로 설정되지 않은 경우보다 클라이언트측 및 서버측 모두에서 리소스를 더 많이 사용합니다.

  • getBlob 또는 getClob 메서드 대신 getAsciiStream, getBinaryStream, 또는 getCharacterStream 메서드를 사용하여 큰 텍스트 또는 이진 값을 스트림으로 읽습니다. 버전 1.2 릴리스 이상에서는 이러한 작업을 위해 SQLServerCallableStatement 클래스에 새로운 get<Type>Stream 메서드가 제공됩니다.

  • SELECT 문에서 잠재적으로 큰 값을 갖는 열이 열 목록의 마지막에 배치되도록 하고 SQLServerResultSetget<Type>Stream 메서드를 사용하여 해당 메서드가 선택된 순서로 해당 열에 액세스하도록 합니다.

  • SQLServerCallableStatement 생성에 사용된 SQL에서 잠재적으로 큰 값을 갖는 OUT 매개 변수가 매개 변수 목록의 마지막에 선언되도록 합니다. 또한 SQLServerCallableStatementget<Type>Stream 메서드를 사용하여 해당 메서드가 선언된 순서로 OUT 매개 변수에 액세스하도록 합니다.

  • 둘 이상의 문이 같은 연결에서 동시에 실행되지 않도록 합니다. 이전 문의 결과를 처리하기 전에 다른 문을 실행하면 처리되지 않은 결과가 응용 프로그램 메모리에 버퍼링될 수 있습니다.

  • 다음과 같은 경우에는 responseBuffering=adaptive 대신 selectMethod=cursor를 사용하는 것이 더 좋습니다.

    • 응용 프로그램이 사용자 입력을 받은 후 각 행을 읽는 등 정방향 읽기 전용 결과 집합을 천천히 처리하는 경우 responseBuffering=adaptive 대신 selectMethod=cursor를 사용하면 SQL Server에 의한 리소스 사용을 줄일 수 있습니다.

    • 응용 프로그램이 동일한 연결에서 동시에 둘 이상의 정방향 읽기 전용 결과 집합을 처리하는 경우 responseBuffering=adaptive 대신 selectMethod=cursor을 사용하면 이러한 결과 집합을 처리하는 동안 드라이버에 필요한 메모리를 줄일 수 있습니다.

    두 경우 모두 서버 커서를 만들고 읽고 닫을 때 발생하는 오버헤드를 고려해야 합니다.

또한 다음 목록에서는 스크롤 및 업데이트가 가능한 정방향 전용 결과 집합에 대한 권장 사항에 대해 설명합니다.

  • 스크롤 가능한 결과 집합의 경우 행 블록을 인출할 때 드라이버는 선택 버퍼링이 설정된 경우에도 항상 SQLServerResultSet 개체의 getFetchSize 메서드가 나타내는 행 수를 메모리로 읽어들입니다. 스크롤로 인해 OutOfMemoryError가 발생하는 경우 SQLServerResultSet 개체의 setFetchSize 메서드를 호출하여 인출 크기를 더 적은 행 수(필요한 경우 1도 가능)로 설정함으로써 인출되는 행 수를 줄일 수 있습니다. 이렇게 해도 OutOfMemoryError, 가 발생하는 경우에는 스크롤 가능한 결과 집합에 아주 큰 열을 포함하지 마십시오.

  • 업데이트 가능한 정방향 결과 집합의 경우 행 블록을 인출할 때 드라이버는 해당 연결에 대해 선택 버퍼링이 설정된 경우에도 일반적으로 SQLServerResultSet 개체의 getFetchSize 메서드가 나타내는 행 수를 메모리로 읽어들입니다. SQLServerResultSet 개체의 next 메서드를 호출하여 OutOfMemoryError가 발생하는 경우 SQLServerResultSet 개체의 setFetchSize 메서드를 호출하여 인출 크기를 더 적은 행 수(필요한 경우 1도 가능)로 설정함으로써 인출되는 행 수를 줄일 수 있습니다. 또한 문을 실행하기 전에 "adaptive" 매개 변수를 사용하여 SQLServerStatement 개체의 setResponseBuffering 메서드를 호출하여 드라이버가 행을 버퍼링하지 않도록 지시할 수 있습니다. 결과 집합을 스크롤할 수 없으므로 응용 프로그램이 get<Type>Stream 메서드 중 하나를 사용하여 큰 열 값에 액세스하는 경우 드라이버는 정방향 읽기 전용 결과 집합을 처리할 때와 마찬가지로 응용 프로그램이 값을 읽는 즉시 해당 값을 삭제합니다.

참고

관련 자료

JDBC 드라이버로 성능 및 안정성 개선