今日もプログラミング

IT技術とかプログラミングのこととか特にJavaを中心に書いていきます

embulk-output-sqlserverのパフォーマンスを計測したら結構速かった

embulk-output-sqlserverとは

embulkとは、オープンソースのバルクデータ転送ツールである。

そして、embulk-output-sqlserverとは、embulkのプラグインの1つで、SQL Serverにデータをロードするためのものである。

これを使うと、CSVファイルとか他のデータベースから、SQL Serverにデータをロードすることができる。

 

データベースとバルクロード

データベースに大量にデータ投入するとき、INSERT文で1レコードずつ入れていくと非常に時間が掛かる。

そのため、各DBMSはバルクロード用のツールを用意している。

OracleであればSQL*Loader、SQL Serverであればbcp、などだ。

 

embulk-output-jdbcのデフォルトの実装では、JDBC経由でレコードをINSERTする。

embulkはマルチスレッドで実行されるが、それでもかなり時間が掛かる。

そこで、DBMSのバルクロード用のAPIを利用し、高速化を図っている。

今のところ、OracleSQL Serverでこの手法を実現している。

 

計測結果

計測環境は、サーバとクライアントともにAWSのc3.2xlargeインスタンス(8 vCPU、15GiB メモリ、SSD)。

使用した各ソフトウェアのバージョンは下表の通り。

Windows Server 2012 R2 Standard edition (64bit)
SQL Server 2016 R2 Standard edition
embulk 0.8.12
embulk-input-filesplit 0.1.3
embulk-output-sqlserver 0.6.3

 

入力は、約10GB(50,000,000レコード)のCSVファイル。

テーブル定義は、こんな感じ。

CREATE TABLE EXAMPLE1 (
    ID DECIMAL(12,0),
    NUM DECIMAL(12,0),
    MONTH CHAR(2),
    VALUE1 VARCHAR(20),
    VALUE2 VARCHAR(20),
    VALUE3 VARCHAR(20),
    VALUE4 VARCHAR(20),
    VALUE5 VARCHAR(20),
    VALUE6 VARCHAR(20),
    VALUE7 VARCHAR(20),
    VALUE8 VARCHAR(20),
    VALUE9 VARCHAR(20),
    VALUE10 VARCHAR(20),
    PRIMARY KEY(ID)
);

embulik-input-filesplitは、ファイルを並列で読み込むためのプラグインだ。

embulk-output-sqlserverには、JDBCでINSERTするモード(normal)と、バルクロードのAPISQL Server Native Client)を利用するモード(native)があり、両方測ってみた。

また、embulkはマルチスレッド動作するが、タスク数も変えて測ってみた。

比較のため、bcpでも測っている。

ログを見ると1,000行ずつ送信していて、遅そうだったので、-b 10000を指定してみたら、速くなった。

 

ツールタスク数時間(分)
embulk-output-sqlserver(normal) + embukl-input-filesplit 8 219.0
embulk-output-sqlserver(native) + embukl-input-filesplit 1 27.8
2 18.1
4 15.4
8 9.6
bcp - 17.6
bcp -b 10000 - 11.7

 

まとめ

normalモードが遅いのは予想通りとして、nativeモードが予想以上に速かった。

bcpも、デフォルトのままでなく適切に-bオプションを設定すると結構速くなるようだ。

もちろん、環境とかテーブルぞ構造とかによってパフォーマンスは変わるが、embulk-output-sqlserverは十分速いと言えそうだ。