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を利用し、高速化を図っている。
今のところ、OracleとSQL 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)と、バルクロードのAPI(SQL 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は十分速いと言えそうだ。