つかびーの技術日記

情報系修士卒のWeb系技術日記です。現在のフォーカス分野はアドテクです。

AWS RDS(MySQL)とImpalaを比較!同一テストデータで検証してみる

   

前回の投稿でAWS EMR上でImpalaを動作させてみました。

動作させてみたのは良いのですが、本当に早いのかイマイチ分かりません。

そこで同一のテストデータをAWS RDS(MySQL)に投入して、そちらで何秒かかるのか計測してみたいと思います。

結論としてはクエリによりけりですが、5倍〜30倍、Impalaの方が早いです。

RDS環境構築

まずはRDSを用意します。

MySQLを選択。

RDS Management Console

今回は検証なので、障害とか考えなくてよい為、Multi AZなどはOFFにします。

RDS Management Console2

以下のように設定します。

インスタンスは1台あたりの料金がImpalaのときと同じくらいの料金であるdb.m3.mediumを選択します。1時間10円ほどです。(もっともEMR+Impalaでやったときはインスタンスは合計3台だったので、この時点で不公平ではあるのですが。とりあえず先へ進みます。)

DBは初め5GBで作って足りてましたが、後でALTER TABLEするときに足りなくなりました。10GBくらいはあった方が良いです。

本当はProvisioned IOPSは使った方が早いのですが、とりあえず今回はOFFで。

RDS Management Console3

この辺りは適当に。

選択したVPC SecurityによってはMySQLのポート3306が閉じられているため、後で管理画面から確認しておきます。閉じられていたら空けておきます。

RDS Management Console4

Backupは不要なので0にします。

これでLaunch DBして作成開始です。

RDS Management Console5

結構かかります。5分ほど待ちます。

最終的に以下のようにavailableになると完了です。

RDS Management Console6

テストデータ作成

RDSは残念ながら直接SSH接続することはできません。そのため、テストデータは一旦ローカル(Mac)に作成してからLOAD DATA LOCAL INFILEコマンドで取り込むことにします。合計3GBあるのでかなりきついですが。。。この辺りもっと上手い方法あれば教えてください。

まずはImpalaのときと同じようにテストデータを用意します。

これで前回同様booksファイルなどができました。

次はいよいよMySQLの方で操作をしていきます。

まずはログインします。RDS管理画面上のEndpointという部分にホスト名が載っているのでこれを使って以下のように接続します。

ホスト名、ユーザ名は各自変えます。パスワードは管理画面で先ほど登録したものです。

次はテーブルを作成します。Impalaの例の方だとisbnなどはSTRING型なのですが、MySQLには無いのでVARCHARにしました。

確認です。

作成できたので次はテストデータを投入します。books, customers, transactionsファイルのパスは各自変えます。自分の場合は以下のような感じです。

やはりここが長いです。バルクインポートとは言え、合計3GBのデータをネットワーク越しに投入しているのでそりゃ時間かかりますね。同一LANのEC2上から上記コマンド実行した方が圧倒的に早いと思います。

ここでいくつかwarningが発生します。これはテストデータの中に1970-01-01というデータがあるためです。MySQLのTIMESTAMP型が許可する値は1970-01-01 00:00:01〜ですが、上記のテストデータをインポートしようとすると1970-01-01が1970-01-01 00:00:00に変換され、範囲を超えちゃっているため発生しています。一部のデータが0000-00-00 00:00:00になってますが、まあ問題ない件数なので無視します。

3つのデータが無事入ったので、いよいよSQLを実行してみます。(ちなみにうちは光回線ですが20分かかりました)

クエリ実行

ではいよいよImpalaの方と同じクエリを発行してみたいと思います。ちなみに検索結果が違うのは上記のWarningのせいです。

クエリ1つめ。

クエリ2つめ。

クエリ3つめ。[SHUFFLE]は指定できない為、外しました。

クエリ4つめ。[SHUFFLE]は指定できない為、外しました。

こんな感じになりました。

クエリ1と2しか計測できてませんが、MySQLよりImpalaの方が5倍以上高速ですね。クエリ3と4については、そもそもMySQLだと絶望的なので、Impalaが何倍高速なのか分かりません。分かりませんが、クエリ3は30分以上待っても結果が帰らないことから、少なくともImpalaの方が60倍以上高速であることが分かります。

クエリ実行(インデックスありバージョン)

上記のテーブルはインデックスがありません。そのため全体的に損しています。折角なのでインデックスを作成して同様のクエリを投げてみたいと思います。

インデックスを作成する前にRDSのストレージサイズを5GBから10GBに変更しておきます。ALTER TABLEでテーブルコピーが発生しますが、このとき空きが足りなくなる為です。(ERROR 1114 (HY000): The table ‘#sql-2895_6’ is fullというようなエラーが出ます。)

次にインデックスを作成します。

3つ目のALTERは外部キー設定があって、処理時間がやばいことになるので一旦チェック処理を外しています。チェック処理ありだと数時間かかるかと思います。

これだけでも合計1時間近くかかりました。

ではクエリを実行してみます。

クエリ1つめ。

クエリ2つめ。

クエリ3つめ。

クエリ4つめ。

インデックスのおかげで早くなってます。

クエリ1は圧倒的に早いですね。B木の一部分だけ取ってきて、そこをcountすればいいだけなので当然早くなります。

クエリ2は若干早くなっています。whereが無いので結局全レコード調べなくちゃならないので遅いですね。

クエリ3は結果が帰ってきたことに驚きました。自分の知識ではなんで早くなったか分かりませんが。結合部分のインデックスで結合対象絞れるし、group by のcategoryでもサマる対象の部分木がすぐ取れるからでしょうか。結局これもクエリ1のように処理対象大きく削れる訳じゃないので遅いですが。

クエリ4はやっぱり遅いですね。これだけGROUP BYとJOINしてれば当然ですね。

まとめ

という訳でImpalaめっちゃ早いです!group byはRDBMSでは限界ありますね。

簡単に処理時間をグラフ化してみました。一部数値出てないので完璧なグラフじゃありませんが。

[visualizer id=”585″]

Impala早いですね。

きっちりした検証ではありませんが、Impala早いという感触を得ることができました。

 - MySQL , , ,