0.CSVネタの準備
郵便番号のCSVがあったのでこれを使おうと思いましたが、思うところあって約50MBのデータを自作しました。1フィールド目=番号、2フィールド目=番号のSha1値という非常に簡単なもので、100万行分作成しました。(Pythonで作成してます)
↓こんな感じ…
------------------------------------------------
1,356a192b7913b04c54574d18c28d46e6395428ab
2,da4b9237bacccdf19c0760cab7aec4a8359010b0
3,77de68daecd823babbb58edb1c8e14d7106e83bb
…
999999,1f5523a8f535289b3401b29958d01b2966ed61d2
1000000,b27585828a675f5acfef052dd1a8cf0c6c1ee4b0
------------------------------------------------
↓Pythonで作成する際は以下のような感じで・・・
---------------------------------------------------
import hashlib
i=0
while i < 1000000:
i += 1
print str(i)+","+hashlib.sha1(str(i)).hexdigest()
---------------------------------------------------
尚、以下の確認は家のローカルPC(Dell製)で行いましたが、
CPU→ Celeron(R) Dual-Core CPU T3000 @ 1.80GHz
OS→ Fedora13
です。
1.MongoDB
MongoDBにはmongoimportコマンドというものがあり、CSVファイルを一括ローディング可能です。以下のような形で実行しました。今回はtimeコマンドで時間を測定しています。
[user@user ~]$ time mongoimport -d test -c hash --dbpath /home/user/mongodata/ -f id,value --type csv --file /tmp/neta.csv
testデータベースのhashコレクションにid,valueというカラムを持ったneta.csvを格納します。結果は以下です。
----------------------
real 0m40.137s
user 0m30.579s
sys 0m8.410s
----------------------
何度か行いましたが、大体同じような結果になりました。
尚、他のデータでもやってみましたが、mongoimportコマンドは数字のみの値については全てnumber型?と解釈するようで、前に0が埋まっている数字を文字列としてローディングしようとしても前0は全てカットされました。また"--type CSV"を指定しないと、大量のエラーが出力されます。
※MongoDBのバージョンはv1.6.2です。
2.Sqlite3
.import コマンドによりCSVネタのローディングが可能です。
まず、TABLEを作成しました。
sqlite> create table hash ( id INTEGER PRIMARY KEY , value TEXT );
その後、
以下のコマンドでローディングを行います。
[user@user ~]$ time sqlite3 testdb ".import '/tmp/neta.csv' hash"
testdbのhashテーブルに対してneta.csvをローディングしました。結果は以下の通りです。
----------------------
real 0m8.961s
user 0m6.609s
sys 0m0.949s
----------------------
すこしはまったのですが、sqlite3はデフォルトのDelimiterは"|"らしいのでCSVネタを
1|356a192b7913b04c54574d18c28d46e6395428ab
のように作成しなおしました。
※Sqlite3のバージョンは3.6.22です
3.PostgreSQL
COPYコマンドによりCSVの一括ローディングが出来ます。
まず、以下でテーブルを作ります。
testdb=# create table hash ( id integer PRIMERY KEY , value TEXT ) ;
その後、
COPY hash FROM '/tmp/neta.csv' DELIMITER '|' ;
と記載したファイル(copy.txt)を作成し、以下を実行します。-bash-4.1$ time psql testdb -f /tmp/copy.txt
testdbに対してcopy.txtに記載してあるCOPYコマンドを実行しました。結果は以下の通りです。
----------------------
real 0m12.746s
user 0m0.001s
sys 0m0.003s
----------------------
※PostgreSQLのバージョンは9.0です。
まとめ
Realだけで比較すると以下になります。
Mongodb…0m40.137s
Sqlite3…0m8.961s
Postgresql…0m12.746s
パフォーマンスが一番良いと勝手に考えていたMongoDBは実は一番悪いという結果になりました。もちろんこれだけでその製品のパフォーマンスを語る事は出来ませんが、少なくともCSVのローディング機能についてはSqlite3やPostgreSQLに軍配があがりました。
と言うか、MongoDB遅すぎっ!
これがMongoDBの構造的な問題なのか、まだまだ改善の余地があるのかは不明です。また、上記確認ですが、全てインストール時のデフォルトの状態で実施しており、何らかのパラメータをいじってチューニング、、、みたいな事は一切していません。