EC2からRDSにLOAD DATA LOCAL INFILEでインポートしてみる

RDSにデータを高速にインポートしたい。LOAD DATA LOCAL INFILEが動くのか試していた。
MySQL DB インスタンスからのデータのインポートおよびエクスポート - Amazon Relational Database Service
ドキュメントによると、LOAD DATA LOCAL INFILEは使えるらしい。
EC2にUbuntuインスタンスを作成し、EC2からRDSのMySQLに対してデータを投入してみた。
確認したバージョンは、Ubuntu 14.04, MySQL 5.6。EC2とRDSのインスタンスの種類は共にm3.medium。

準備

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install mysql-client-5.6

対象のデータベーステーブルのDDL

ID値、文字列、数値を格納できる単純なテーブルの定義です。

CREATE TABLE `mytable` (
  `id` INTEGER(10) NOT NULL auto_increment,
  `value1` VARCHAR(37) NOT NULL,
  `value2` INTEGER(4) NOT NULL,
  PRIMARY KEY(id)
);

この定義でテーブルを作っておきます。
インデックスがある場合は削除してからロードしたほうがいいかもしれない。

読み込ませるデータ

Pythonスクリプトを書いて読み込ませるTSV形式のデータを生成しました。

# make_data.py
import sys
import uuid
import random

def main():
    id_ = 0
    while True:
        id_ += 1
        if id_ > 15000000:
            break
        value1 = uuid.uuid4()
        value2 = random.randrange(1000)
        sys.stdout.write("{}\t{}\t{}\n".format(id_, value1, value2))

if __name__ == '__main__':
    main()
$ python make_data.py > input.tsv
$ ls -lh input.tsv
-rw-rw-r-- 1 ubuntu ubuntu 704M Sep 15 15:47 input.tsv

ファイルサイズは700MB程度。

ロードする

EC2のインスタンスからMySQLクライアントでRDSに接続し、LOAD DATA LOCAL INFILEクエリを投げてみます。
Ubuntuなのでapparmorがデフォルトで有効になっていますが、あらかじめ停止しています。

LOAD DATA LOCAL INFILE '/home/ubuntu/input.tsv'
 INTO TABLE mytable
 FIELDS TERMINATED BY '\t';

RDSに接続して実行してみます。

$ mysql -u myuser -h testdb.csyajfcwd1d7.ap-northeast-1.rds.amazonaws.com -D test -p
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 35
Server version: 5.6.23 MySQL Community Server (GPL)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> LOAD DATA LOCAL INFILE '/home/ubuntu/input.tsv'
    ->  INTO TABLE mytable
    ->  FIELDS TERMINATED BY '\t';
Query OK, 15000000 rows affected (2 min 35.12 sec)
Records: 15000000  Deleted: 0  Skipped: 0  Warnings: 0

2分半程度で1500万件のインポートが完了しました。

データの確認

mysql> SELECT COUNT(*) FROM mytable;
+----------+
| COUNT(*) |
+----------+
| 15000000 |
+----------+
1 row in set (4.65 sec)

mysql> SELECT * FROM mytable LIMIT 5;
+----+--------------------------------------+--------+
| id | value1                               | value2 |
+----+--------------------------------------+--------+
|  1 | c3334206-8b02-4860-a939-c42c2df07978 |     88 |
|  2 | 8affc52f-e499-4225-9ae0-0cdddb094106 |    285 |
|  3 | dea4d9c8-2c4f-45ed-b517-11e768ae9bc2 |     51 |
|  4 | 7e751411-18d5-4413-8bf7-da479ca91c0a |    458 |
|  5 | 9afda3cb-6c50-4dd8-b0a7-c4e410deb6f3 |    130 |
+----+--------------------------------------+--------+
5 rows in set (0.00 sec)

問題なさそうでした。