성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>무료 데이터베이스 서버 성능 비교(SQL Server Express, IBM DB2 Express, MySQL, Sybase, PostgreSQL, Oracle XE)</h1> <p> 지난 글에서 각종 DB에 대한 접속 방법을 테스트 해보았는데요.<br /> <br /> <ul> <li>SQL Server 2012 Express</li> <li>IBM DB2 Express-C is a community edition of the DB2 10.1 (<a target='tab' href='http://www.sysnet.pe.kr/2/0/1407'>http://www.sysnet.pe.kr/2/0/1407</a>)</li> <li>MySQL 5.5.28 (<a target='tab' href='http://www.sysnet.pe.kr/2/0/1405'>http://www.sysnet.pe.kr/2/0/1405</a>)</li> <li>Sybase: SQL Anywhere 12.0.1 Developer Edition (<a target='tab' href='http://www.sysnet.pe.kr/2/0/1410'>http://www.sysnet.pe.kr/2/0/1410</a>)</li> <li>PostgreSQL 9.0 (<a target='tab' href='http://www.sysnet.pe.kr/2/0/961'>http://www.sysnet.pe.kr/2/0/961</a>)</li> <li>Oracle XE 11g (<a target='tab' href='http://www.sysnet.pe.kr/2/0/1316'>http://www.sysnet.pe.kr/2/0/1316</a>)</li> </ul> <br /> 기왕 테스트 환경을 만든 김에 간단한 성능 테스트 까지 해보았습니다. 다음과 같이 간단한 테이블을 만들고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > DB(Schema): mytestdb 테이블: mytable 칼럼: id int NOT NULL PK name varchar(50) age int description varchar(150) * 테이블 생성 후 레코드를 10개씩만 추가 </pre> <br /> .NET Framework 4.0 x64에서 다음의 SQL Server 연동 코드와 동일한 방식으로 테스트 해보았습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string connectionString = ...; using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { sqlConnection.Open(); // Create SqlCommand insertCommand = new SqlCommand(); insertCommand.Connection = sqlConnection; insertCommand.CommandText = "INSERT INTO mytable(id, NAME, age, DESCRIPTION) VALUES (@id, @NAME, @age, @DESCRIPTION)"; insertCommand.Parameters.Add("@id", SqlDbType.Int); insertCommand.Parameters.Add("@NAME", SqlDbType.VarChar, 50); insertCommand.Parameters.Add("@age", SqlDbType.Int); insertCommand.Parameters.Add("@DESCRIPTION", SqlDbType.VarChar, 150); string nameValue = "Name" + Guid.NewGuid().ToString(); insertCommand.Parameters[0].Value = (int)DateTime.Now.Ticks; insertCommand.Parameters[1].Value = nameValue; insertCommand.Parameters[2].Value = 10; insertCommand.Parameters[3].Value = nameValue + "_Description"; int affected = insertCommand.ExecuteNonQuery(); Console.WriteLine("# of affected row: " + affected); // Update SqlCommand updateCommand = new SqlCommand(); updateCommand.Connection = sqlConnection; updateCommand.CommandText = "UPDATE mytable SET DESCRIPTION=@DESCRIPTION WHERE NAME=@NAME"; updateCommand.Parameters.Add("@NAME", SqlDbType.VarChar, 50); updateCommand.Parameters.Add("@DESCRIPTION", SqlDbType.VarChar, 150); updateCommand.Parameters[0].Value = nameValue; updateCommand.Parameters[1].Value = nameValue + "_Description2"; affected = updateCommand.ExecuteNonQuery(); Console.WriteLine("# of affected row: " + affected); // Select - ExecuteScalar SqlCommand selectCommand = new SqlCommand(); selectCommand.Connection = sqlConnection; selectCommand.CommandText = "SELECT count(*) FROM mytable"; object result = selectCommand.ExecuteScalar(); Console.WriteLine("# of records: " + result); // Select - DataTable DataSet ds = new DataSet(); SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM mytable", sqlConnection); da.Fill(ds, "mytable"); DataTable dt = ds.Tables["mytable"]; foreach (DataRow dr in dt.Rows) { Console.WriteLine(string.Format("Name = {0}, Desc = {1}", dr["NAME"], dr["DESCRIPTION"])); } // Delete SqlCommand deleteCommand = new SqlCommand(); deleteCommand.Connection = sqlConnection; deleteCommand.CommandText = "DELETE FROM mytable WHERE NAME=@NAME"; deleteCommand.Parameters.Add("@NAME", SqlDbType.VarChar, 50); deleteCommand.Parameters[0].Value = nameValue; affected = deleteCommand.ExecuteNonQuery(); Console.WriteLine("# of affected row: " + affected); } </pre> <br /> 보신 바와 같이, 테스트에 있어 어떤 기준이나 의미를 처음부터 구상하고 만든 것이 아닙니다. 그냥 말 그대로 간단한 테스트입니다.<br /> <br /> C#으로 위의 코드를 각각 포함하는 6개 웹 페이지를 만들었습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > http://win2008r2:8010/PostgreSQLDefault.aspx http://win2008r2:8010/MySqlDefault.aspx http://win2008r2:8010/MssqlDefault.aspx http://win2008r2:8010/OracleDefault.aspx http://win2008r2:8010/SybaseDefault.aspx http://win2008r2:8010/DB2Default.aspx </pre> <br /> 그리고 부하 발생기는 간단한 C# 클라이언트를 만들어서 했습니다. 그런데, 테스트 대상인 DB들 중에는 무료 버전이 심각하게 기능 제한을 한 것이 있어서, 2 TPS(Transaction per second) 정도만 요청을 보내는 것으로 했습니다. 부하 테스트가 아니므로, 평상시의 쿼리 수행 시간에 대한 비교를 할 수 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 테스트의 시각화를 위해 "<a target='tab' href='http://www.jennifersoft.com/docs/ms-dotnet-performance-management.html'>제니퍼 닷넷</a>"을 사용했습니다. 자... 각각의 DB에 어떤 결과가 나오는지 한번 볼까요? ^^<br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>1. DB2: 무난한 성능</div> <br /> 뭐 별로 특이 사항 없이 무난합니다. 우측 상단의 X-View라는 것을 보면 Y축이 응답시간이고, X축은 웹 페이지를 요청했던 시간입니다. 즉, 대부분의 aspx 요청에 대한 처리가 1초 안에 완료된 것을 볼 수 있습니다.<br /> <br /> 다른 DB와의 성능 비교용으로 이걸 기준으로 잡아도 될 것 같습니다. ^^<br /> <br /> <img alt='db2_perf_1.png' src='/SysWebRes/bbs/db2_perf_1.png' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>2. MySQL: 눈에 띄게 낮은 성능</div> <br /> 개인적으로 MySQL의 테스트 결과가 의외였는데요. 그래도 오픈 소스에서는 나름 명성이 있는 만큼 무난한 성능을 기대했는데 그렇지 않았습니다. 아래의 결과를 보면, X-View에서도 단순한 쿼리 테스트일 뿐인데도 aspx 처리에 보통 2 ~ 3초는 걸리고 있습니다. 이 결과를 보면... 사실 MySQL에서 다른 DB로 이전하는 것만으로도 상당한 성능 효과를 볼 수 있습니다.<br /> <br /> <img alt='mysql_perf_1.png' src='/SysWebRes/bbs/mysql_perf_1.png' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>3. Microsoft SQL Server</div> <br /> 역시 무난합니다. 1초 내로 거의 모든 aspx 웹 페이지 처리가 완료되고 있습니다. 게다가 "힙 메모리 사용률"부분은 DB2 보다도 좀 더 안정적인 상황을 보여줍니다. DB2의 경우 사실 Unmanaged + Managed ADO.NET Provider입니다. 그런데, X-View 아래의 "최근 힙 메모리 사용률"에는 "Managed Heap" 변화만 나타는데요. 순수 Managed로 이뤄진 System.Data.dll이 Unmanaged를 함께 사용한 수준보다 낮게 힙 변화가 나온다는 것은 굉장히 최적화가 잘 되었다고 판단될 수 있습니다.<br /> <br /> <img alt='mssql_perf_1.png' src='/SysWebRes/bbs/mssql_perf_1.png' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>4. Oracle</div> <br /> 오라클도 무난합니다. 오라클 역시 Unmanaged + Managed이기 때문에 "최근 힙 메모리 사용률"을 보면 상당히 낮은 변화량을 볼 수 있습니다. 흠잡을 것이 없군요. ^^<br /> <br /> <img alt='oracle_perf_1.png' src='/SysWebRes/bbs/oracle_perf_1.png' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>5. Sybase</div> <br /> Sybase도 무난합니다. sybase도 Unmanaged + Managed라는 점을 감안하면 "최근 힙 메모리 사용률"이 오라클 수준으로 낮을 수 있는데 그렇지 못한 것을 볼 수 있습니다. 순수 Managed로만 이뤄진 System.Data보다 높은 변동률을 보이는데요. 아무래도 최적화가 덜 된 것이라고 짐작됩니다.<br /> <br /> Sybase의 경우 X-View 상세 보기에 나온 쿼리 프로파일 내용에 특이한 것이 발견되었습니다. Connection Open을 할 때마다 무조건 서버로 "SELECT @@version"라는 쿼리를 한번 실행하는 것이 확인되었습니다. 어쩔 때는 이것만으로 <a target='tab' href='https://www.sysnet.pe.kr/2/0/11063'>16ms가 소요</a>되기도 합니다.<br /> <br /> 그렇게 쿼리 한번의 부하가 있다고 해도, 전반적인 성능은 MySQL보다 우수합니다.<br /> <br /> <img alt='sybase_perf_1.png' src='/SysWebRes/bbs/sybase_perf_1.png' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>6. PostgreSQL</div> <br /> PostgreSQL의 ADO.NET Data Provider는 순수하게 Managed입니다. 그래서 힙 메모리 사용률이 조금 요동을 치는 것 같습니다.<br /> <br /> PostgreSQL도 Sybase처럼 Connection Open 시에 무조건 "Select 1"이라는 쿼리를 항상 실행합니다. 물론, 그래도 MySQL보다 우수한 성능을 보이고 있습니다.<br /> <br /> <img alt='postgre_perf_1.png' src='/SysWebRes/bbs/postgre_perf_1.png' /><br /> <br /> <hr style='width: 50%' /><br /> <br /> MySQL의 성능이 낮은 것에 대한 이유는 잘 파악이 안 됩니다. 어쩌면 MySQL용 ADO.NET Provider가 최적화가 안 되어 그런 성능을 나타내는 걸 수도 있습니다. 그렇다고는 해도... 최소한 닷넷 프로젝트에서는 MySQL을 쓰는 것은 안 좋은 선택인 것 같습니다. 차라리, 같은 무료 DB 서버인 PostgreSQL를 권장하고 싶습니다. ^^<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1862
(왼쪽의 숫자를 입력해야 합니다.)