GA

2014/09/16

LOAD DATA INFILEで複数ファイルを食わせるのにちょっとだけ有効なTIPS

LOAD DATA INFILEで複数のファイルを順番(じゃなくてもいいけど)食わせる場合を考える。

↓こんなかんじ


$ ll *.tsv
-rw-rw-r-- 1 mysql mysql 541810051 Sep 16 10:51 20140912.tsv
-rw-rw-r-- 1 mysql mysql 523910384 Sep 16 10:52 20140913.tsv
-rw-rw-r-- 1 mysql mysql 513351897 Sep 16 10:53 20140914.tsv
-rw-rw-r-- 1 mysql mysql 513221906 Sep 16 10:54 20140915.tsv


無圧縮なファイルなら、シェルでぐるんぐるん回すのが便利。

$ for f in *.tsv ; do
> mysql -sse "LOAD DATA INFILE $f INTO TABLE .." && gzip $f
> done


成功したらgzip圧縮とかそのまんま書けるのでラク。
ただし、圧縮ファイルだと"展開" => "LOAD DATA INFILE" => "再圧縮"とか書くのはちょっと面倒だしなんかイヤだ。
あと、InfiniDBはある程度(100万行くらいだっけ?)まとめてLOAD DATA INFILEに食わせた方がデータの構築とかいっぺんに出来て速いとかそんな感じだった気がする(infinidb_use_import_for_batchinsert= 1の場合。0(MySQLのLOAD DATA INFILEをそのまま使う)場合はよく知らない)

という訳で、mkfifoを使ってます。


$ ll *.tsv.gz
-rw-rw-r-- 1 mysql mysql  2778925 Sep 12 18:04 20140722.tsv.gz
-rw-rw-r-- 1 mysql mysql  6775101 Sep 12 18:04 20140723.tsv.gz
-rw-rw-r-- 1 mysql mysql  7715720 Sep 12 18:04 20140724.tsv.gz
-rw-rw-r-- 1 mysql mysql  7811469 Sep 12 18:04 20140725.tsv.gz
-rw-rw-r-- 1 mysql mysql  8329598 Sep 12 18:05 20140726.tsv.gz
-rw-rw-r-- 1 mysql mysql  8256156 Sep 12 18:05 20140727.tsv.gz
-rw-rw-r-- 1 mysql mysql  8081465 Sep 12 18:05 20140728.tsv.gz
-rw-rw-r-- 1 mysql mysql  7881025 Sep 12 18:05 20140729.tsv.gz
-rw-rw-r-- 1 mysql mysql  7496167 Sep 12 18:06 20140730.tsv.gz
-rw-rw-r-- 1 mysql mysql  7934078 Sep 12 18:06 20140731.tsv.gz

$ mkfifo /tmp/fifo

$ zcat *.tsv.gz > /tmp/fifo


別のターミナルから

$ mysql -sse "LOAD DATA INFILE /tmp/fifo INTO TABLE .."

どうせLOAD DATA INFILEに失敗したらTRUNCATEして入れなおすからこれで十分。

0 件のコメント :

コメントを投稿