Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

무료 데이터베이스 서버 성능 비교(SQL Server Express, IBM DB2 Express, MySQL, Sybase, PostgreSQL, Oracle XE)

지난 글에서 각종 DB에 대한 접속 방법을 테스트 해보았는데요.


기왕 테스트 환경을 만든 김에 간단한 성능 테스트 까지 해보았습니다. 다음과 같이 간단한 테이블을 만들고,

DB(Schema): mytestdb
테이블: mytable
        칼럼:  id int NOT NULL PK
               name varchar(50)
               age int
               description varchar(150) 

* 테이블 생성 후 레코드를 10개씩만 추가

.NET Framework 4.0 x64에서 다음의 SQL Server 연동 코드와 동일한 방식으로 테스트 해보았습니다.

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);
}

보신 바와 같이, 테스트에 있어 어떤 기준이나 의미를 처음부터 구상하고 만든 것이 아닙니다. 그냥 말 그대로 간단한 테스트입니다.

C#으로 위의 코드를 각각 포함하는 6개 웹 페이지를 만들었습니다.

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

그리고 부하 발생기는 간단한 C# 클라이언트를 만들어서 했습니다. 그런데, 테스트 대상인 DB들 중에는 무료 버전이 심각하게 기능 제한을 한 것이 있어서, 2 TPS(Transaction per second) 정도만 요청을 보내는 것으로 했습니다. 부하 테스트가 아니므로, 평상시의 쿼리 수행 시간에 대한 비교를 할 수 있습니다.




테스트의 시각화를 위해 "제니퍼 닷넷"을 사용했습니다. 자... 각각의 DB에 어떤 결과가 나오는지 한번 볼까요? ^^


1. DB2: 무난한 성능

뭐 별로 특이 사항 없이 무난합니다. 우측 상단의 X-View라는 것을 보면 Y축이 응답시간이고, X축은 웹 페이지를 요청했던 시간입니다. 즉, 대부분의 aspx 요청에 대한 처리가 1초 안에 완료된 것을 볼 수 있습니다.

다른 DB와의 성능 비교용으로 이걸 기준으로 잡아도 될 것 같습니다. ^^

db2_perf_1.png


2. MySQL: 눈에 띄게 낮은 성능

개인적으로 MySQL의 테스트 결과가 의외였는데요. 그래도 오픈 소스에서는 나름 명성이 있는 만큼 무난한 성능을 기대했는데 그렇지 않았습니다. 아래의 결과를 보면, X-View에서도 단순한 쿼리 테스트일 뿐인데도 aspx 처리에 보통 2 ~ 3초는 걸리고 있습니다. 이 결과를 보면... 사실 MySQL에서 다른 DB로 이전하는 것만으로도 상당한 성능 효과를 볼 수 있습니다.

mysql_perf_1.png


3. Microsoft SQL Server

역시 무난합니다. 1초 내로 거의 모든 aspx 웹 페이지 처리가 완료되고 있습니다. 게다가 "힙 메모리 사용률"부분은 DB2 보다도 좀 더 안정적인 상황을 보여줍니다. DB2의 경우 사실 Unmanaged + Managed ADO.NET Provider입니다. 그런데, X-View 아래의 "최근 힙 메모리 사용률"에는 "Managed Heap" 변화만 나타는데요. 순수 Managed로 이뤄진 System.Data.dll이 Unmanaged를 함께 사용한 수준보다 낮게 힙 변화가 나온다는 것은 굉장히 최적화가 잘 되었다고 판단될 수 있습니다.

mssql_perf_1.png


4. Oracle

오라클도 무난합니다. 오라클 역시 Unmanaged + Managed이기 때문에 "최근 힙 메모리 사용률"을 보면 상당히 낮은 변화량을 볼 수 있습니다. 흠잡을 것이 없군요. ^^

oracle_perf_1.png


5. Sybase

Sybase도 무난합니다. sybase도 Unmanaged + Managed라는 점을 감안하면 "최근 힙 메모리 사용률"이 오라클 수준으로 낮을 수 있는데 그렇지 못한 것을 볼 수 있습니다. 순수 Managed로만 이뤄진 System.Data보다 높은 변동률을 보이는데요. 아무래도 최적화가 덜 된 것이라고 짐작됩니다.

Sybase의 경우 X-View 상세 보기에 나온 쿼리 프로파일 내용에 특이한 것이 발견되었습니다. Connection Open을 할 때마다 무조건 서버로 "SELECT @@version"라는 쿼리를 한번 실행하는 것이 확인되었습니다. 어쩔 때는 이것만으로 16ms가 소요되기도 합니다.

그렇게 쿼리 한번의 부하가 있다고 해도, 전반적인 성능은 MySQL보다 우수합니다.

sybase_perf_1.png


6. PostgreSQL

PostgreSQL의 ADO.NET Data Provider는 순수하게 Managed입니다. 그래서 힙 메모리 사용률이 조금 요동을 치는 것 같습니다.

PostgreSQL도 Sybase처럼 Connection Open 시에 무조건 "Select 1"이라는 쿼리를 항상 실행합니다. 물론, 그래도 MySQL보다 우수한 성능을 보이고 있습니다.

postgre_perf_1.png




MySQL의 성능이 낮은 것에 대한 이유는 잘 파악이 안 됩니다. 어쩌면 MySQL용 ADO.NET Provider가 최적화가 안 되어 그런 성능을 나타내는 걸 수도 있습니다. 그렇다고는 해도... 최소한 닷넷 프로젝트에서는 MySQL을 쓰는 것은 안 좋은 선택인 것 같습니다. 차라리, 같은 무료 DB 서버인 PostgreSQL를 권장하고 싶습니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/2/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2013-02-01 04시32분
[Lyn] 감사합니다.

근데 mysql 은 원래 느렷어요 (...)
[guest]
2013-02-01 04시33분
[Lyn] 혹시 테스트한 mysql 환경의 스토리지 엔진이 MyISAM인지 InnoDB인지 확인 가능할까요
[guest]
2013-02-01 10시29분
InnoDB입니다. @hjAnyflow 님이 다음과 같은 의견을 주셨네요. ^^

"mysql보다 postgres를 쓰는 이유는 낮은 성능에도 불구하고 sharding에서 일관된 성능을 보이기 때문이다.. 이런 리포트가 꽤 도는 현실이라서리... mysql의 낮은 성능결과는 드라이버 등의 외부요인이 클듯하네요. 오라클보다 빠르다는 이야기가 많고, 특히나 postgres보다는 특히나 더 그렇고요.."

나중에 시간되면,,, ^^ 한번 더 테스트를 해봐야겠습니다.
정성태
2013-02-01 11시59분
[Lyn] 단순 Select가 아니라면 mysql 이 빠를일은 없을겁니다 아마도 ...

Join 한번만 걸어도 속도가 산으로 가는놈이라 ㅡ.ㅡ;
[guest]
2013-02-04 02시47분
[dummy] MySQL에서 분리된 마리아DB는 좀 다른 모습을 보여줄까요?
[guest]
2013-02-04 05시11분
[Lyn] 마리아DB 최신버전은 Mysql과 잘 호환되지 않습니다... 자기들도 그걸 인식하는지 별도의 커넥터를 제공하더라구요.

마리아DB최신버전에 Mysql 닷넷커넥터 최신버전으로 연결시 몇몇 쿼리에서 에러가 발생했습니다.
[guest]
2013-02-13 11시48분
Sysbench OLTP: MySQL-5.6 vs. MariaDB-10.0
; http://blog.mariadb.org/sysbench-oltp-mysql-5-6-vs-mariadb-10-0/
정성태
2014-04-16 04시46분
[손님2] MYSQL은 드라이버 문제라기보다 예전부터 윈도우 버전의 최적화가 되지 않아서 리눅스 버전보다 성능이 좋지 못했습니다.
아무래도 크로스로 지원하다보니 윈도우에 특화된? 기능들을 활용하지 않았기 때문이라고 생각되고요.
MariaDB 도 MYSQL에서 포크된 후 수정이 되고 있으니 같을거라고 추측합니다..

그리고 mysql 과 mssql 을 비교하는건 별로 올바르지 못하다고 생각되는데 mssql 은 기업내에서 bi나 미션크리티컬한 환경등 엔터프라이즈한 기능들이 대부분이고 mysql 은 rdbms 가 느리다고 상당부분을 전부 제거한체 라이트하게 나온 거의 파일디비에 가깝다고 압니다.
작년인가 오라클이 mysql 을 mssql 에서 마이그레이션하게끔 유도하는 기사나? 마케팅을 펼치는건 db를 대체할 수 있다기 보다 수준이 오라클db 보다 낮다는걸 어필하기 위한 성격이 가능하다고 생각 됩니다.

mysql 이 다른 db들과 비교하는 글들이 웹사에서 올라오는데 초창기처럼 라이트하게 속도빠른 db로 남았으면 좋겠습니다.-_-
[guest]
2023-04-18 09시52분
[guest] 100만점에 100점 - Sqlite는 없지만
[guest]

... 61  62  63  64  65  66  67  68  69  70  71  72  [73]  74  75  ...
NoWriterDateCnt.TitleFile(s)
11817정성태2/17/20199954오류 유형: 514. WinDbg Preview 실행 오류 - Error : DbgX.dll : WindowsDebugger.WindowsDebuggerException: Could not load dbgeng.dll
11816정성태2/17/201912468Windows: 157. 윈도우 스토어 앱(Microsoft Store App)을 명령행에서 직접 실행하는 방법
11815정성태2/14/201911358오류 유형: 513. Visual Studio 2019 - VSIX 설치 시 "The extension cannot be installed to this product due to prerequisites that cannot be resolved." 오류 발생
11814정성태2/12/201910169오류 유형: 512. VM(가상 머신)의 NT 서비스들이 자동 시작되지 않는 문제
11813정성태2/12/201911756.NET Framework: 809. C# - ("Save File Dialog" 등의) 대화 창에 확장 속성을 보이는 방법
11812정성태2/11/20199624오류 유형: 511. Windows Server 2003 VM 부팅 후 로그인 시점에 0xC0000005 BSOD 발생
11811정성태2/11/201913389오류 유형: 510. 서버 운영체제에 NVIDIA GeForce Experience 실행 시 wlanapi.dll 누락 문제
11810정성태2/11/201911453.NET Framework: 808. .NET Profiler - GAC 모듈에서 GAC 비-등록 모듈을 참조하는 경우의 문제
11809정성태2/11/201912943.NET Framework: 807. ClrMD를 이용해 메모리 덤프 파일로부터 특정 인스턴스를 참조하고 있는 소유자 확인
11808정성태2/8/201914007디버깅 기술: 123. windbg - 닷넷 응용 프로그램의 메모리 누수 분석
11807정성태1/29/201912322Windows: 156. 가상 디스크의 용량을 복구 파티션으로 인해 늘리지 못하는 경우 [4]
11806정성태1/29/201912055디버깅 기술: 122. windbg - 덤프 파일로부터 PID와 환경 변수 등의 정보를 구하는 방법
11805정성태1/28/201913907.NET Framework: 806. C# - int []와 object []의 차이로 이해하는 제네릭의 필요성 [4]파일 다운로드1
11804정성태1/24/201911949Windows: 155. diskpart - remove letter 이후 재부팅 시 다시 드라이브 문자가 할당되는 경우
11803정성태1/10/201911447디버깅 기술: 121. windbg - 닷넷 Finalizer 스레드가 멈춰있는 현상
11802정성태1/7/201912819.NET Framework: 805. 두 개의 윈도우를 각각 실행하는 방법(Windows Forms, WPF)파일 다운로드1
11801정성태1/1/201913855개발 환경 구성: 427. Netsh의 네트워크 모니터링 기능 [3]
11800정성태12/28/201813144오류 유형: 509. WCF 호출 오류 메시지 - System.ServiceModel.CommunicationException: Internal Server Error
11799정성태12/19/201813955.NET Framework: 804. WPF(또는 WinForm)에서 UWP UI 구성 요소 사용하는 방법 [3]파일 다운로드1
11798정성태12/19/201813195개발 환경 구성: 426. vcpkg - "Building vcpkg.exe failed. Please ensure you have installed Visual Studio with the Desktop C++ workload and the Windows SDK for Desktop C++"
11797정성태12/19/201810552개발 환경 구성: 425. vcpkg - CMake Error: Problem with archive_write_header(): Can't create '' 빌드 오류
11796정성태12/19/201810208개발 환경 구성: 424. vcpkg - "File does not have expected hash" 오류를 무시하는 방법
11795정성태12/19/201812606Windows: 154. PowerShell - Zone 별로 DNS 레코드 유형 정보 조회 [1]
11794정성태12/16/20189998오류 유형: 508. Get-AzureWebsite : Request to a downlevel service failed.
11793정성태12/16/201811622개발 환경 구성: 423. NuGet 패키지 제작 - Native와 Managed DLL을 분리하는 방법 [1]
11792정성태12/11/201812384Graphics: 34. .NET으로 구현하는 OpenGL (11) - Per-Pixel Lighting파일 다운로드1
... 61  62  63  64  65  66  67  68  69  70  71  72  [73]  74  75  ...