As Published In

Oracle Magazine
2005년 9월/10월
개발자: ODP.NET

바인드의 가치
Mark A. Williams

바인드 변수와 ODP.NET을 사용한 .NET 애플리케이션의 성능 향상

.NET 애플리케이션에서 Oracle Database의 데이터에 액세스하는 방법에는 여러 가지가 있습니다. 그러나 기능과 성능의 관점에서 볼 때 .NET 애플리케이션을 Oracle Database와 연결하는 방법으로는 Oracle Data Provider for .NET(ODP.NET)가 가장 좋은 선택입니다.

본 컬럼에서는 ODP.NET 10g의 핵심 기능을 통해 .NET 애플리케이션을 향상시킬 수 있는 방법을 중심으로 살펴보기로 하겠습니다. 첫 번째 주제는 ODP.NET 10g와 함께 바인드 변수를 사용하는 방법에 대한 것입니다.

바인드 변수 사용

ODP.NET 10g가 효율적으로 작동하고 확장되도록 만들기 위한 가장 간편하고 효과적인 방법 중 하나는 바인드 변수를 적절히 사용하는 것입니다. 바인드 변수는 다양한 유형의 애플리케이션 성능 향상에 도움이 되지만 여기서는 ODP.NET 10g와 함께 사용하는 경우에 대해 살펴보겠습니다.

바인드 변수는 SQL 문의 위치 표시자입니다. 예를 들어 Oracle Database와 함께 제공되는 HR 샘플 스키마를 사용할 경우, 바인드 변수를 사용하지 않는 일반적인 SELECT 문은 다음과 같습니다.

select country_name
from hr.countries
where country_id = 'UK'

보는 것처럼 문의 WHERE 절에 리터럴 텍스트를 ‘UK’로 지정하였습니다. 간단히 한 가지를 변경하여 바인드 변수를 사용하도록 문을 변환할 수 있습니다.

select country_name
from hr.countries
where country_id = :country_id

바인드 변수를 사용하는 문으로 변환하기 위해 리터럴 텍스트 ‘UK’를 :country_id로 식별되는 위치 표시자로 바꾸었습니다. 이 바인드 변수 식별자는 단일 콜론(":")으로 시작되는데 이것은 바인드 변수가 SQL 문에서 어떻게 나타나는지를 보여줍니다.

여기서는 SELECT 문을 사용하여 바인드 변수의 용도를 예시하였으나 바인드 변수는 UPDATE, INSERT, DELETE 문에서도 사용될 수 있으며 또 사용해야 합니다. 다음은 같은 countries 테이블을 사용하여 UPDATE 문에서 바인드 변수를 사용한 예입니다.

update hr.countries
set country_name  = :country_name
where country_id   = :country_id

바인드 변수가 중요한 이유

Oracle Database 10g가 SQL 문으로 제시되면 메모리 영역인 공유 풀을 확인하여 해당 문이 이미 존재하는지, 그 문이 메모리에 저장되어 있는지를 확인합니다. 해당 문이 메모리에 이미 존재하고 Oracle Database 10g가 해당 문을 재사용할 수 있으면 데이터베이스는 이 문의 구문 분석과 최적화 작업을 생략하고 건너뛸 수 있습니다. 바인드 변수를 사용하는 경우에는 SQL 문이 메모리에 저장될 가능성이 매우 높아지므로 SQL 문을 필요로 하는 후속 작업에서 이 문을 신속하게 사용할 수 있습니다.

공유 풀에 해당 문이 존재하지 않는 경우, 데이터베이스는 해당 문에 대한 구문 분석과 최적화 작업을 수행해야 하므로 성능이 저하될 수 있습니다. 문의 구문 분석과 최적화 작업에는 CPU 주기가 소모되며 소모되는 CPU 주기가 많을수록 작업은 더 느려지게 됩니다. 구문 분석과 최적화 작업은 또한 래치라는 메커니즘을 통해 공유 풀의 다양한 부분을 잠금 상태로 두게 됩니다. 한 번에 하나의 프로세스만 래치를 유지할 수 있으므로 공유 풀에 래칭이 증가하면 데이터베이스 안에서 경합이 벌어지게 됩니다.

단일 사용자 시스템에서는 래치가 발생하는 양과 문의 구문 분석 및 최적화에 사용되는 시간이 별로 중요하지 않게 보일 수 있습니다. 그러나 시스템에 사용자가 계속 추가되거나 애플리케이션의 추가 복사본이 실행되면 이러한 이벤트는 순식간에 늘어날 수 있으며 심지어는 시스템을 사용불능 상태로 만들 수도 있습니다.

ODP.NET 10g에서 바인드 변수 구현

ODP.NET 10g 프로그램에서 바인드 변수를 사용하려면 OracleParameter 클래스를 사용하여 .NET 코드로 각 바인드 변수를 표시합니다. OracleParameterCollection 클래스는 그 이름으로 알 수 있듯이 각 문에 대한 OracleCommand 객체와 관련된 OracleParameter 객체를 포함하는 수집 클래스입니다. OracleCommand 클래스는 SQL 문을 데이터베이스에 전달하고 그 결과를 애플리케이션에 반환합니다.

ODP.NET 10g에서는 bind by position(기본값) 또는 bind by name이라는 바인드 변수를 사용하는 두 가지 모드를 사용할 수 있습니다. OracleCommand의 부울 속성 BindByName(기본값은 false)이 모드를 설정합니다. bind by position 모드를 사용할 경우 SQL 문에 보이는 것과 같은 순서로 OracleParameterCollection 모음에 이 매개변수를 추가해야 합니다. 명령어 객체에 대한 모음에 매개변수를 추가하려면 Parameters 속성에서 Add 메소드를 사용합니다. bind by name 모드를 사용할 경우는 이 모음에 어떤 순서로 매개변수를 추가해도 관계 없으나, 해당 매개변수 객체에 대한 ParameterName 속성을 SQL 문의 바인드 변수 식별자와 같은 값으로 설정해야 합니다.

바인딩 모드(by position 또는 by name) 외에도 일반적으로 각 매개변수 객체에 대해 다음과 같은 몇 가지 속성을 설정합니다.

  • Direction
  • OracleDbType
  • Size
  • Value

바인드 변수는 출력, 입력 또는 입/출력 매개변수로 사용될 수 있습니다. 각 매개변수에 대해 적절한 방향을 표시하려면 Direction 속성을 사용합니다. Direction 속성의 기본값은 Input.입니다. 이 매개변수가 숫자, 날짜, VARCHAR2 등 가운데 어떤 것인지 표시하려면 OracleDbType 속성을 사용합니다. VARCHAR2 데이터 유형과 같은 변수 길이 데이터 유형을 사용할 경우, 매개변수가 가지고 있는 데이터의 최대 크기를 표시하려면 Size 속성을 사용합니다. Value 속성에는 문 실행 전(입력 매개변수의 경우), 실행 후(출력 매개변수의 경우), 또는 전후(입/출력 매개변수의 경우)의 매개변수 값이 들어있습니다.

목록 1의 Main 메소드는 이러한 개념들을 하나로 묶어주며 SELECT 문에서 바인드 변수를 사용합니다. 다음은 Main 메소드의 핵심 부분입니다.

OracleCommand cmd = 
new OracleCommand(); 

?명령 객체(OracleCommand) 생성

OracleParameter p_country_id = 
new OracleParameter();

?매개변수 객체(OracleParameter) 생성

p_country_id.OracleDbType = OracleDbType.Varchar2;
p_country_id.Value = "UK";

?매개변수 객체의 OracleDbTypeValue 속성 설정
다음 단계

ODP.NET에 대한 추가 정보
Oracle Data Provider for .NET 개발자 가이드

다운로드
이 컬럼에 대한 샘플 애플리케이션
ODP.NET 10g
Oracle Developer Tools for Visual Studio .NET

Direction 속성이 기본값 Input을 사용하며 Size 속성은 설정되어 있지 않은 점에 주의하십시오. 이 객체는 입력 매개변수이므로 속성을 설정할 필요가 없습니다. Data Provider가 해당 값의 크기를 결정할 수 있기 때문입니다.

cmd.Parameters.Add(p_country_id);

?모음에 매개변수 추가

목록 1의 샘플 애플리케이션을 실행하려면 .NET 콘솔 애플리케이션을 생성하고 메소드의 본문으로서 목록 1 코드를 사용하여 Main 메소드를 생성합니다. 프로젝트에 ODP.NET 10g 어셈블리에 대한 참조를 추가하고 코드 모듈 상단에 Oracle .DataAccess.Client 이름 공간을 포함시켜야 합니다. 참조를 추가하려면 Microsoft Visual Studio .NET 2003 메뉴 표시줄에서 Project -> Add Reference...를 선택한 다음 Add Reference 대화상자에서 Oracle .DataAccess.dll을 선택합니다. 이름 공간을 포함시키려면 using Oracle.DataAccess.Client;를 코드 모듈 상단에 추가합니다. 출력 결과는 다음과 같습니다.

C:\VTB\bin\Release>ValuesThatBind.exe

Country Name: United Kingdom

코드 목록 1: 바인드 변수 사용

static void Main(string[] args)
{
  string constr = "User Id=hr; Password=hr; Data Source=oramag";

  OracleConnection con = new OracleConnection(constr);
  con.Open();

  StringBuilder sbSQL = new StringBuilder();
  sbSQL.Append("select    country_name ");
  sbSQL.Append("from      countries ");
  sbSQL.Append("where     country_id = :country_id");

  OracleCommand cmd = new OracleCommand();
  cmd.Connection = con;
  cmd.CommandText = sbSQL.ToString();

  OracleParameter p_country_id = new OracleParameter();
  p_country_id.OracleDbType = OracleDbType.Varchar2;
  p_country_id.Value = "UK";

  cmd.Parameters.Add(p_country_id);

  OracleDataReader dr = cmd.ExecuteReader();

  if (dr.Read())
  {
    Console.WriteLine("Country Name: {0}", dr.GetOracleString(0));
  }

  dr.Dispose();
  p_country_id.Dispose();
  cmd.Dispose();
  con.Dispose();
}

바인드 변수: 계속 사용 권장

본 컬럼에서는 .NET 애플리케이션에서 ODP.NET 10g와 함께 간단한 바인드 변수를 사용하는 방법에 대해 설명했습니다. 바인드 변수를 사용할 때와 그렇지 않은 경우에 대해 각 애플리케이션을 테스트하여 바인드 변수의 이점을 확인해 보시기 바랍니다..


Mark A. Williams (mawilliams@cheshamdbs.com)는 Oracle ACE, Oracle Certified Professional DBA이며 Pro .NET Oracle Programming(Apress, 2004)의 저자입니다. Williams는 Windows용 오라클 솔루션에 집중하고 있으며 Oracle Technology Network의 Oracle Data Provider for .NET 포럼에 기고하고 있습니다.

의견 보내기

E-mail this page
Printer View Printer View