「MySQL Database Serviceへ移行してみよう」 でも簡単にご紹介しましたが、昨年の11月に、Oracle Cloud の MySQL Database Service に、HeatWave
というインメモリで列指向な分析処理を高速化させるエンジンが使用できるようになりました。
HeatWave は分析処理を非常に高速化することができ、これにより、MySQLを使用していても、分析用途としてはMySQL以外のETLツールを使用されているようなケースでは、MySQLに統一する事でシステムを単純化させる事が可能となります。
今回は、その HeatWave について簡単に検証してみたいと思います。
詳細についてのリファレンスは、以下をご参照下さい。
事前準備
まずは、MySQL Database Service のインスタンスを作成します。
インスタンスの作成方法については以下が参考になるかと思いますので、初めての方はご参考にして頂ければと思います。
※HeatWave を使用する際は、インスタンス作成時の「シェイプの選択」で、「MySQL.HeatWave.VM.Standard.E3」もしくは「BM.Standard.E2.64」を選択する必要があります。
もし、シェイプの選択画面にそれらが表示されない場合は、サービス制限の引き上げリクエストを行って下さい。
インスタンスを作成したら、検証用にデータを作成しておきます。
別のパブリックサブネットにComputeインスタンスを作成して、そのインスタンスから、本ブログでも何度かご紹介している sysbench を使用して、5000万件のレコードを持つテーブルを1つ作成しました。
1 2 3 4 5 6 7 8 9 |
sysbench --db-driver=mysql \ --mysql-host=<MySQL Database Service Endpoint> \ --mysql-user=<User> \ --mysql-password=<User Password> \ --mysql-db=sysbench \ --tables=1 \ --table_size=50000000 \ oltp_read_only \ prepare |
HeatWaveクラスタの作成
検証用のデータを作成後に、HeatWave のクラスタを作成します。
MySQL Database Service のインスタンス詳細画面を表示し、画面左のリソースメニューから「HeatWave」を選択して「HeatWaveクラスタの追加」ボタンを押下します。
表示された画面から「シェイプ」と「ノード数」を指定します。
ノード数は最低でも 2 以上を設定する必要があります。
また、「ノード数の見積り」ボタンを押下すると、以下のように現在の存在するスキーマ、テーブル情報等から、最適なノード数を設定する事が可能です。
クラスタ作成後は、10分程度で「Heatwaveの状態」が「アクティブ」となりました。
対象テーブルに SECONDARY_ENGINE を設定
HeatWaveクラスタを作成しただけでは、HeatWaveにデータは存在しません。
まずは、MySQL Database Service インスタンスに接続し、HeatWave を使用する対象テーブルの SECONDARY_ENGINE
を RAPID
に設定します。
1 2 3 |
mysql> ALTER TABLE sysbench.sbtest1 SECONDARY_ENGINE RAPID; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 |
実行後にテーブル定義を確認すると、SECONDARY_ENGINE=RAPID
が設定されています。
1 2 3 4 5 6 7 8 9 10 11 |
mysql> SHOW CREATE TABLE sysbench.sbtest1 \G *************************** 1. row *************************** Table: sbtest1 Create Table: CREATE TABLE `sbtest1` ( `id` int NOT NULL AUTO_INCREMENT, `k` int NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=50000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci SECONDARY_ENGINE=RAPID |
これで、テーブルの全てのカラムが HeatWaveクラスタで処理する対象となりますが、一部のカラムのみを除外することも可能です。
方法については、HeatWave User Guide / 3.2 Excluding Table Columns をご参照下さい。
HeatWaveクラスタにデータロード
次にHeatWaveクラスタにデータをロードします。
以下のように ALTER TABLE で SECONDARY_LOAD
を指定します。
1 2 |
mysql> ALTER TABLE sysbench.sbtest1 SECONDARY_LOAD; Query OK, 0 rows affected (3 min 1.58 sec) |
3分程かかりましたが、実行中に rapid_load_progress
変数を確認する事で進捗状況を確認できます。
値が 100 になれば完了となります。
1 2 3 4 5 6 7 8 |
mysql> SELECT VARIABLE_VALUE -> FROM performance_schema.global_status -> WHERE VARIABLE_NAME = 'rapid_load_progress'; +----------------+ | VARIABLE_VALUE | +----------------+ | 47.347771 | +----------------+ |
完了して使用できる状態であるかは、performance_schema.rpd_tables で確認することができます。
AVAIL_RPDGSTABSTATE
は、HeatWaveクラスタへデータのロードが完了し、アクセス可能である状態を示します。
1 2 3 4 5 6 7 8 |
mysql> SELECT NAME, LOAD_STATUS -> FROM performance_schema.rpd_tables, performance_schema.rpd_table_id -> WHERE rpd_tables.ID = rpd_table_id.ID; +------------------+---------------------+ | NAME | LOAD_STATUS | +------------------+---------------------+ | sysbench.sbtest1 | AVAIL_RPDGSTABSTATE | +------------------+---------------------+ |
1度ロードしてしまえば、以降の更新データは自動的にHeatWaveクラスタへ反映されますが、HeatWaveを再起動した場合には、再度、ロードする必要があります。
また、HeatWaveクラスタのデータを削除したい場合は、ALTER TABLE で SECONDARY_UNLOAD
を指定します。
1 2 |
mysql> ALTER TABLE sysbench.sbtest1 SECONDARY_UNLOAD; Query OK, 0 rows affected (0.04 sec) |
SQLの実行
ここまでの手順で、HeatWaveクラスタにデータを配置できたので、SQLを実行して確認してみます。
sysbench で作成したテーブル構成は、以下のような構成になっています。
1 2 3 4 5 6 7 8 9 10 11 |
mysql> SHOW CREATE TABLE sysbench.sbtest1 \G *************************** 1. row *************************** Table: sbtest1 Create Table: CREATE TABLE `sbtest1` ( `id` int NOT NULL AUTO_INCREMENT, `k` int NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=50000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci SECONDARY_ENGINE=RAPID |
登録データは、主キーとなる id には連番、数値型の k と 文字列型の c, pad には乱数が設定されています。
1 2 3 4 5 6 |
mysql> SELECT * FROM sysbench.sbtest1 LIMIT 1 \G *************************** 1. row *************************** id: 1 k: 21416420 c: 83868641912-28773972837-60736120486-75162659906-27563526494-20381887404-41576422241-93426793964-56405065102-33518432330 pad: 67847967377-48000963322-62604785301-91415491898-96926520291 |
それでは、数値型の k に対して範囲検索を実行します。
1 2 3 4 5 6 7 |
mysql> SELECT COUNT(*) from sysbench.sbtest1 WHERE k BETWEEN 1000000 AND 7000000; +----------+ | COUNT(*) | +----------+ | 5996586 | +----------+ 1 row in set (0.02 sec) |
0.02秒
となりました。EXPLAINで実行計画を確認してみます。
1 2 3 4 5 6 |
mysql> EXPLAIN SELECT COUNT(*) from sysbench.sbtest1 WHERE k BETWEEN 1000000 AND 7000000; +----+-------------+---------+------------+------+---------------+------+---------+------+----------+----------+-------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+------+----------+----------+-------------------------------------------+ | 1 | SIMPLE | sbtest1 | NULL | ALL | NULL | NULL | NULL | NULL | 49337064 | 25.98 | Using where; Using secondary engine RAPID | +----+-------------+---------+------------+------+---------------+------+---------+------+----------+----------+-------------------------------------------+ |
Extra列の Using secondary engine RAPID
の出力からHeatWaveクラスタで処理していると判断できます。
5000万件のレコードをフルスキャンして 0.1秒以下でレスポンスを返すのは、とんでもなく早いように思います。
また、必ずHeatWaveクラスタで処理される訳ではなく、HeatWaveクラスタで処理しても恩恵がないと判断された場合には、通常のストレージエンジンで処理される為、実行計画を確認するようにしましょう。
それでは、HeatWaveクラスタを使用しない場合には、どの位の時間がかかるか確認したいと思います。
HeatWaveクラスタで実行させないように、use_secondary_engine=OFF
を設定します。
1 2 |
mysql> SET SESSION use_secondary_engine=OFF; Query OK, 0 rows affected (0.00 sec) |
同じSQLで実行計画を確認します。
Extra列に Using secondary engine RAPID
の出力がない事から、HeatWaveクラスタで処理されないことが確認できます。
1 2 3 4 5 6 |
mysql> EXPLAIN SELECT COUNT(*) from sysbench.sbtest1 WHERE k BETWEEN 1000000 AND 7000000; +----+-------------+---------+------------+-------+---------------+------+---------+------+----------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+-------+---------------+------+---------+------+----------+----------+--------------------------+ | 1 | SIMPLE | sbtest1 | NULL | range | k_1 | k_1 | 4 | NULL | 12819264 | 100.00 | Using where; Using index | +----+-------------+---------+------------+-------+---------------+------+---------+------+----------+----------+--------------------------+ |
それでは、実際にSQLを実行します。
1 2 3 4 5 6 7 |
mysql> SELECT COUNT(*) from sysbench.sbtest1 WHERE k BETWEEN 1000000 AND 7000000; +----------+ | COUNT(*) | +----------+ | 5996586 | +----------+ 1 row in set (1.18 sec) |
実行結果は、1.18秒
となりました。
HeatWaveクラスタで処理した際は 0.02秒
だったので、60倍程度
の大きな差が見られました。
次は以下のようなSQLで、c列の先頭3桁でグルーピングして、k列の値の合計が高い順に5レコード抽出してみます。
1 2 3 4 5 6 7 8 9 10 |
SELECT LEFT(c, 3) AS code3, SUM(k) AS total FROM sysbench.sbtest1 GROUP BY code3 ORDER BY total DESC LIMIT 5\G |
まずは、HeatWaveクラスタを使用しない状態で実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
mysql> SELECT -> LEFT(c, 3) AS code3, -> SUM(k) AS total -> FROM -> sysbench.sbtest1 -> GROUP BY -> code3 -> ORDER BY -> total DESC -> LIMIT 5\G *************************** 1. row *************************** code3: 208 total: 1270005592386 *************************** 2. row *************************** code3: 256 total: 1268412672822 *************************** 3. row *************************** code3: 352 total: 1267512774521 *************************** 4. row *************************** code3: 223 total: 1266787620751 *************************** 5. row *************************** code3: 487 total: 1265247331153 5 rows in set (46.47 sec) |
46.67秒
となりました。
HeatWaveクラスタを使用した場合を見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
mysql> SET SESSION use_secondary_engine=ON; Query OK, 0 rows affected (0.00 sec) mysql> SELECT -> LEFT(c, 3) AS code3, -> SUM(k) AS total -> FROM -> sysbench.sbtest1 -> GROUP BY -> code3 -> ORDER BY -> total DESC -> LIMIT 5\G *************************** 1. row *************************** code3: 208 total: 1270005592386 *************************** 2. row *************************** code3: 256 total: 1268412672822 *************************** 3. row *************************** code3: 352 total: 1267512774521 *************************** 4. row *************************** code3: 223 total: 1266787620751 *************************** 5. row *************************** code3: 487 total: 1265247331153 5 rows in set (1.82 sec) |
1.82秒
だったので、HeatWaveクラスタを使用しない場合と比較して、25倍程度
と非常に高速化されています。
今回は、特に分析用途としたSQLではなく簡易的な検証ではありますが、HeatWaveクラスタで処理速度が圧倒的に早くなる事を確認できたかと思います。
また、複雑なSQLの実行やクラスタノードを増やすことで更に速度差の違いが感じられることかと思います。
まとめ
今回、ご紹介させて頂いたMySQLで稼働する分析エンジン HeatWave は、非常に高速に処理を行えるようになっており、興味が沸いた方もおられるのではないでしょうか。
現在は、オンプレや他社クラウドを使用されている場合でも、そこから、MySQL Database Service にレプリケーションして HeatWave を使用するといった用途でも使用可能です。
HeatWave には、勿論制限等もございますので、利用をご検討頂く際には、以下のリファレンスをご確認頂く事をお勧めします。
- HeatWave User Guide / 10.1 Supported Data Types
- HeatWave User Guide / 10.2 Supported Functions and Operators
- HeatWave User Guide / 10.6 Limitations