본문 바로가기

TechLog

Reader 객체에서 인덱스/필드 이름으로 필드 값을 가져올 때의 속도 비교

Reader 객체에서 인덱스/필드 이름으로 필드 값을 가져올 때의 속도 비교

ADO.net을 사용하면서 필드 값을 가져올 때 필드의 인덱스를 사용하십니까, 필드 이름을 사용하십니까? 사소한 부분이긴 하지만 이 또한 성능 개선에 보탬이 될 수 있습니다.

 

 

Kenial 은 데이터베이스 프로그래밍을 할 때 SqlDataReader, OleDbReader를 사용하는 경우가 많습니다. 보통은 데이터베이스 변경이 자주 일어나곤 해서 필드 이름으로 필드의 값을 가져오는 쪽을 선호합니다만, 코드를 한참 입력해 넣다가 보니 이게 성능 차이가 얼마나 날까 궁금해져서 실험해 본 결과를 정리해 보았습니다.

 

그럼 시작합니다 :

 

 

인덱스를 쓸 것이냐 필드 이름을 쓸 것이냐

 

temp = reader[0];
temp = reader["ID"];

 

위 코드는 ado.net Reader 객체에서 필드 값을 가져올 때 쓰는 코드이다. 아무래도 필드 이름을 사용하면 레코드에서 필드 이름에 해당하는 데이터를 검색하는 오버헤드가 생길텐데, 필드 이름 대신 인덱스를 사용하면 성능의 개선이 있을까?

 

실험 환경은 다음과 같다 :

  Amd Athlon-XP-Mobile 2000+, 512MB Ram

  Windows 2003 server standard, Sql Server 2000, Access 2003

  데이터 :

    필드는 ID(int, Primary Key), TestField1(string)

    ID에는 일련번호가 들어가 있고,

    TestField1에는 'a', 'b', 'c', 'a', 'b', ... 가 반복적으로 129024건의 레코드가 입력되어 있음

 

실제 코드는 다음과 같다 (인덱스/Access DB 사용) :

 

comm.CommandText = "Select * From TestTable";

...

starttime = DateTime.Now;   // 현재 시간 기록(시작)

for(i=0; i<10; i++)

{

    reader = comm.ExecuteReader();

    while(reader.Read())

    {

        strTemp = reader[1].ToString();

    };

    reader.Close();

}

endtime = DateTime.Now;     // 현재 시간 기록()

ticks_ms = (endtime.Ticks - starttime.Ticks)  / 10000.0;    // ticks 10000으로 나누면 단위가 된다

strTemp = string.Format("MDB ordinary Time Elapased : {0:#.####}ms<br>", ticks_ms );

Response.Write(strTemp);

 

코드는 ADO.net에서 가장 간단한 형태로 Connection - Command - Reader 객체만으로 데이터베이스를 액세스하도록 하며, 속도 비교가 되는 내용은 다음과 같다 :

1. Command 객체에서 쿼리를 실행, Reader 객체를 리턴받음

2. 처음 레코드부터 끝 레코드까지 TestField1 필드의 값을 읽어들여 strTemp에 저장

3. 1~2 10회 반복

 

인 덱스/필드 이름을 사용했을 때의 속도 비교와 함께 Access / Sql Server를 사용했을 때의 결과는 다음과 같았다 (실행 환경에 따라 가변적이며, Kenial PC에서도 가변적인 결과가 나왔다. 두 개의 결과를 제공한다) :

 

MDB ordinary Time Elapased : 8101.6496ms

MDB named Time Elapased : 8882.7728ms

MS-SQL ordinary Time Elapased : 3214.6224ms

MS-SQL named Time Elapased : 3965.7024ms

 

MDB ordinary Time Elapased : 8061.592ms

MDB named Time Elapased : 8822.6864ms

MS-SQL ordinary Time Elapased : 3314.7664ms

MS-SQL named Time Elapased : 3965.7024ms

 

위의 결과대로, 8~19% 사이의 성능 차이가 있었다.

 

 

정리

 

위 의 실험은 약간 억지스러운 면이 있기는 합니다. 12만개 * 10회에 달하는 레코드를 처음부터 끝까지 탐색하는 경우가 일반적인 상황이라고 보기는 힘드니까요. 하지만 미미한 성능의 차이라고 해도, 대규모의 서비스를 제공하는 경우에는 이런 부분까지 고려해서 프로그래밍해야 할 경우가 분명 있으리라고 봅니다. 물론 데이터베이스가 자주 변경된다든가 하는 경우가 있을 수도 있으니, 코드의 가독성이나 성능이냐라는 측면에서, 적절한 방법을 선택해 사용하시면 되겠죠.

 

그럼 :)