Pages

Showing posts with label Firebird. Show all posts
Showing posts with label Firebird. Show all posts

Saturday, July 28, 2018

DB insertion speed test

To be used in my work, I tested which database inserts the records the fastest. Well, actually it was not much - I just created a table with integer(PK)/timestamp/integer and inserted 1 million records with only PK changing.

Benchmark environment is as follows:
  • Dell Inspiron 7373/i5 8th generation
  • Windows 10 Home
  • Target database(all 32bits)
    • PostgreSQL 10.6: used libpq
    • FIrebird 3.0.3: used OO API (C++)
    • SQLite3: #include <sqlite3.h> // ...... :P
And here comes the results and some remarks. I hope it would help visitors.
(I'm not that much good enough to make something open sourced, so this is the best I can offer to the community...... ;) )
  • Insertion speed
    • 1: SQLite, in-memory database: 2 seconds
    • 2: PostgreSQL, COPY: 5 seconds
    • 3: PostgreSQL, bulk insert: 7 seconds
    • 4: Firebird, bulk insert: 10 seconds
    • 5: SQLite, save to file: 56 seconds
  • Disk I/O
    • Thanks to Windows kernel, if the system receives too many small I/Os, it burdens disk too much, making it to the bottleneck
    • When using SQLite to save the result to disk where bulk insertion is impossible, disk I/O hit 100%
    • In Firebird, bulk insertion is implemented via PSQL, where you send a number of records and the each INSERT line in PSQL sequentially inserts the records; still it burdens the disk I/O very high(around 50%), though lower than SQLite
    • In Firebird, set the page size to at least 8192 to lessen disk I/O burdens
  • Bulk insertion
    • We can speed up the insertion using bulk insertion, but we have some speed bottleneck, regardless of disk I/O.
    • Firebird: 10 records at once, regardless of page size
      • Using stored procedure
    • PostgreSQL: 40 records show the maximum performance
  • PostgreSQL
    • COPY(source: CSV) is incredibly fast. Even the official documentation recommends COPY in bulk insertion
    • In libpq, the speed is around same whether you send the records in either text or binary
  • Miscellany
    • It's far faster to use the official interface directly rather than using any wrapper. When testing Firebird at first, with SOCI it took 59 seconds, while after applying the same logic to Firebird OO API directly the time taken is shrunk to only 20-something seconds.
That's all. Please let me know if you have any questions or comments. =_=/

DB insertion 속도 테스트

업무상 필요로 인해 어느 DB가 record insertion을 제일 빠르게 하는지를 테스트하게 되었습니다. 뭐 대단한걸 한건 아니고, integer(PK)/timestamp/integer로 구성된 테이블에서 PK값만 바꾸고 나머지는 고정값으로 해서 1백만개 레코드를 일괄 등록하는 프로그램을 만들어 돌려봤습니다.

대상 환경은 이렇습니다
  • Dell Inspiron 7373/i5 8세대 모델
  • Windows 10 Home
  • 대상 DB(모두 32비트 모델)
    • PostgreSQL 10.6: libpq 사용
    • FIrebird 3.0.3: OO API (C++) 사용
    • SQLite3: #include <sqlite3.h> // ...... :P
결과 및 시사점을 정리합니다. 도움이 되셨으면 합니다.
(아직 뭔가를 만들어 open source로 만들어 내놓을 정도의 실력이 되지는 않으니 이런거라도......)
  • Insertion 속도
    • 1위: SQLite, in-memory database: 2초
    • 2위: PostgreSQL, COPY: 5초
    • 3위: PostgreSQL, bulk insert: 7초
    • 4위: Firebird, bulk insert: 10초
    • 5위: SQLite, 파일에 저장: 56초
  • Disk I/O 관련
    • Windows 커널 특성상 small I/O가 많아지면 disk에 부담이 너무 많이 가 bottleneck이 됨
    • Bulk insert가 불가능한 SQLite 파일 저장 조건에서 disk I/O가 100%가 됨
    • Firebird의 경우, PSQL을 사용하여 bulk insert를 구현하는 형태로, 다수의 레코드를 한번에 받아 디스크에 개별 INSERT 명령어를 사용하여 순차적으로 쓰는 형태로 구현되므로, SQLite급까지는 아니더라도 disk I/O가 높게 일어남(disk I/O 50%)
    • Firebird의 경우 page size를 최소 8192이상으로 가져가는 것이 disk I/O 부하 감소에 도움이 됨
  • Bulk insertion 관련
    • Bulk insertion을 이용하여 insertion 속도를 올릴 수 있으나, 일정 수준 이상을 넘어서면 속도가 더이상 올라가지 않음. 이는 disk I/O와는 별개임
    • Firebird: 10개 수준에서 최고속력을 보임(page size와 상관없음)
      • Sotred procedure 
    • PostgreSQL: 40개 수준에서 최고속력을 보임
  • PostgreSQL 관련
    • COPY(원본: CSV 기반)가 규격외로 빠른 속력을 보임. 실제로 공식 메뉴얼에서도 bulk insertion에서는 COPY를 추천함
    • libpq에서 insertion 데이터를 보낼때 데이터를 text와 binary 중 어느 형태로 보내도 소요 시간은 동일함
  • 기타
    • 각 DB에서 제공하는 직접 연결 인터페이스를 사용하는 것이 wrapper를 사용하는 것보다 훨씬 빠름. Firebird로 최초 테스트시, SOCI 적용시 59초가 소요되었으나 Firebird OO API로 동일 로직 구현시 20초대에서 완료됨
이정도입니다. 혹시 궁금하신 점이 있으시면 문의 주세요. =_=/

Sunday, February 28, 2016

Building IBPP on MinGW-w64

When building IBPP on MinGW-w64 MinGW complains that "Only Win32 is supported." Hey, I'm on Windows and we're building a Win32 executable!

But well, don't forget we're using an open source project and we're free to review the source code. Let's see _ibpp.h to find out why:
#if (defined(__GNUC__) && defined(IBPP_WINDOWS))
// UNSETTING flags used above for ibase.h -- Huge conflicts with libstdc++ !
#undef _MSC_VER
#undef _WIN32
#endif
As you see, if the compiler is found to be MinGW it #undefs _WIN32. It seems to be because of the compatibility against MinGW 3.0, yet in MinGW-w64 this is the very reason to block the "normal" build.

Hope this would help any Firebird users, who want to use it with IBPP under MinGW-w64.

P.S:
For relations and differences between MinGW and MinGW-w64, please refer to the URLs below:
https://sourceforge.net/p/mingw-w64/wiki2/History/
https://sourceforge.net/p/mingw-w64/wiki2/Feature%20list/

IBPP를 MinGW-w64에서 빌드하려면......

IBPP를 MinGW-w64에서 빌드하려면 갑자기 MinGW가 "Only Win32 is supported!"라는 에러를 내보내면서 빌드가 멈춥니다. Windows에서 빌드하는게 맞는데 Win32만 지원한다면서 투덜대면 이것도 참 황당한데요......

IBPP의 _ibpp.h를 보면 그 원인을 찾을 수 있습니다.
#if (defined(__GNUC__) && defined(IBPP_WINDOWS))
// UNSETTING flags used above for ibase.h -- Huge conflicts with libstdc++ !
#undef _MSC_VER
#undef _WIN32#endif
컴파일러가 MinGW라고 판단되는 경우 _WIN32를 undef하는 것을 보실 수 있습니다. 아마도 MinGW 3.0의 호환성 문제때문에 이렇게 설정한 것 같은데, MinGW-w64에서는 이 구문이 역으로 빌드를 막는 원인이 되는 듯 합니다.

국내에 Firebird를 쓰는 분들, 특히나 IBPP를 MinGW환경에서 사용하실 분들이 몇 분이나 되실지는 모르겠지만, 참고가 되셨으면 합니다.

P.S:
MinGW와 MinGW-w64 프로젝트의 관계 및 차이점에 대해서는 아래의 URL을 참고하세요:
https://sourceforge.net/p/mingw-w64/wiki2/History/
https://sourceforge.net/p/mingw-w64/wiki2/Feature%20list/

Tuesday, August 12, 2014

Lazarus+Firebird+ZeosDBO: Cannot read files in Hangul

When connecting to Firebird using ZeosDBO in Lazarus, if the filename contains Hangul(Korean), the database file cannot be read. Using UTF8ToSys() or Utf8ToAnsi() was of no use. The error occurs when Firebird calls CreateFile(open), though with TIBConnection the file can be read if I apply UTF8ToSys() to DatabaseName.

I liked ZeosDBO as it seems faster that TSQLConection, but now is the time to turn off autocommit and manually do it. Well, considering the origin(a component for Delphi), support for Lazarus is ought to be limited.

Found in following environment:
Lazarus 1.2.4, ZeosDBO 7.1.3a, Firebird 2.5

P.S:Considering the case, the same would happen to files with Chinese or Japanese characters in the name. Pity to CJK users!(including me)

Lazarus+Firebird+ZeosDBO: 한글 파일명 읽기 불가능

Lazarus에서 ZeosDBO를 사용해서 Firebird에 접속할때 파일명이 한글로 되어있으면 파일을 읽지 못하는 문제가 있습니다. UTF8ToSys()나 UTF8ToAnsi()를 사용해도 마찬가지였습니다. 정확히는 Firebird가 파일을 읽기 위해 CreateFile(open)을 호출할때 오류를 일으킵니다. 하지만 TIBConnection은 DatabaseName에 UTF8ToSys()를 적용해주면 정상적으로 동작하더군요.

ZeosDBO가 TSQLConnection보다 속도가 빨라서 좋아했는데, 이젠 TIBConnection에서 autocommit 끄고 돌린 다음에 수동으로 commit하는게 나을 것 같습니다. 아무래도 델파이용으로 만들어진 컴포넌트다보니 Lazarus 지원은 썩 좋지 않은 듯 하네요.

Lazarus 1.2.4, ZeosDBO 7.1.3a, Firebird 2.5에서 확인했습니다.