쓸만한 글

ASP - Command객체를 사용해야 하는 이유

봄돌73 2007. 8. 9. 11:35

출처 : http://blog.naver.com/csaiur/10018250664 (원래의 출처로 갔더니 카페에 가입하라고 해서 포기)

 

 

다음의 예를 실예로 보면서 설명하겠다

strQuery = "SELECT * FROM Orders WHERE OrderDate >= '" & startDate & "' AND OrderDate < '" & endDate & "'"

rs.Open strQuery, adoConn

일단 따옴표(')를 빼먹기 쉽다는 문제는 제쳐 두더라도, 이 쿼리는 SQL 서버 내에서 수행될 때 startDate와
endDate의 값이 변경될 때마다 매번 컴파일 과정을 거쳐야 한다.

불필요한 SQL 컴파일은 DB의 부하를 가중시키켜 성능 저하로 이어지게 된다.

이 문제를 피하려면 파라미터화된 쿼리(Parameterized Query)를 사용하는 것이 좋습니다.
보다시피 따옴표가 사라지고 ? 또는 @로 시작하는 파라미터가 추가되었습니다.

strQuery = "SELECT * FROM Orders WHERE OrderDate >= ? AND OrderDate < ?"

또는

strQuery = "SELECT * FROM Orders WHERE OrderDate >= @startDate AND OrderDate < @endDate"

매개변수를 가진 쿼리를 사용하는 경우에는 매개변수를 넣어주기 위해 반드시 Command 객체를 사용해야 한다.

(아래 예제 참조 )


Set adoCmd = CreateObject("ADODB.Command")
Set adoCmd.ActiveConnection = adoConn
adoCmd.CommandText = strQuery
adoCmd.CommandType = adCmdText '또는 1
adoCmd.Parameters.Append adoCmd.CreateParameter("@startDate", adDate, adParamInput, , startDate)
adoCmd.Parameters.Append adoCmd.CreateParameter("@endDate", adDate, adParamInput, , endDate)

rs.Open adoCmd 'Query 대신 Command 객체를 지정 


이렇게 매개변수를 가진 쿼리를 실행하면, SQL Profiler에서 SQL배치가 아닌 RPC가 수행되어 더욱 속도가 빨라진다.
또한 다음과 같이 매개변수화 되므로 startDate, endDate의 값이 변경되더라도 SQL 컴파일은 한번만 일어나게 된다.

exec sp_executesql N'SELECT * FROM Orders WHERE OrderDate >= @P1 AND OrderDate < @P2 ', N'@P1 datetime,@P2 datetime', '01 1 1995 12:00AM', '01 1 1996 12:00AM'

매개변수를 가진 쿼리는 코드 가독성을 높여주고, 성능 면에서는 좋긴 하지만 코딩량이 다소 늘어난다는 단점
이 있어서 귀차니즘(?) 때문에 안 쓰는 사람들이 많지만..최소한 자주 수행되는 쿼리의 경우 이렇게 작성하면 DB의
부하를 줄이고 성능을 향상시킬 수 있다.

========================= Command 객체의 속성 지정으로 최적화 =====================
우리는 날쿼리를 자주 사용하게 되거나 프로세스 로직이 들어가있는 경우 sp를 사용하게 됩니다.
헌데..날쿼리를 사용하고 Command객체를 사용할경우..
 
  Cmd.Prepared=True 속성이 있다..
-- 이속성은 명령을 실행하기 전에 미리 컴파일해 둘 것인지를 지정하는 속성이다.
   위와 같이 속서을 지정하게 되면..Command 개체는 명령을 실행하기 전에 명령을 컴파일 해서 저장하게된다.
   해서 .. 처음 실행시에는 시간이 조금은 걸리지만 이후 같은 명령을 재실할 경우에는컴파일된 버전을 사용하게
   되므로 속도의 향상 효과를 낼수있다.
   특히.. sp가 아닌 날쿼리로 작성되는 쿼리라면 그리고 특히 페이지 접속이 많은 경우라면
   사용하면 성능의 향상을 꾀할수 있다..

   Cmd.Execute 속성...
   --  Execute [RecordAffected],[Parameters],[Options]

이곳은 다들 알고 있는것이라 생각하므로 Options인자중
잘 쓰지 않는 Opitons중..adExecuteNoRecords를 말하지 않을수 없다.

물론 알고계실것이라 생각들지만..
insert,update,Delete를 할때는 굳이 RecordSet을 생성하지 않아도 된다
이때는 명시적으로 Options 인자중 위의 adExecuteNoRecords를 쓰지 않는경우
보이지 않는 레코드셋이 생성된다.
해서..반드시 adExecuteNoRecords를 쓴다면..레코드셋 객체 자체를 생성치 않으므로..
서버 성능을 꾀할수 있다.

 

 

출처 : http://cafe.naver.com/kes409/325