本記事は MySQL Advent Calendar 2024 の記事です。
はじめに
HeatWave MySQLは、HeatWaveインメモリ・クエリ・アクセラレータを統合したMySQLクラウド・サービスです。他の分析データベースにETLでデータを連携させることなく、トランザクション・データのリアルタイム分析が可能となります。
MySQLのクエリ・パフォーマンスを桁違いに向上させ、複雑さ、レイテンシ、リスク、コストを伴うETL(抽出、変革、ロード)を別の分析データベースに重複させることなく、トランザクション・データをリアルタイム分析します。データ・セキュリティを強化し、Oracle Cloud Infrastructure(OCI)、Amazon Web Services(AWS)、Microsoft AzureにHeatWave MySQL搭載アプリケーションを導入します。
(出典:https://www.oracle.com/jp/mysql/)
基本的にはOracle Cloud Infrastructure(OCI)上で利用可能となるMySQLのクラウドサービス(DBaaS)となりますが、HeatWave on AWSとしてAWSのリソースを利用してAWS上での利用も可能です。
また、Azureでは ODSA(Oracle Database Service for Azure)としてAzure上からOCIのリソースを低レイテンシで利用することが可能となっています。
(出典:Oracle Database Service for Azure)
AWSやAzureについての言及がされている一方で、Google Cloudについて特に言及されていません。
しかしながら、 2024年6月に発表された 通り、Google CloudとOCI間もクロスクラウド接続が可能となっており、低レイテンシ・大容量での通信を行うことが可能です。
したがって、このクロスクラウド接続を利用することでGoogle Cloudからも低レイテンシで HeatWave MySQL を利用することが可能です。
検証構成
今回は次図のようなクロスクラウド接続を構成し、Google Cloud上のVM(Compute Engine)からOCI上の HeatWave MySQL への接続を試みてみます。
Google CloudとOCIのクロスクラウド接続については別途記事を書いておりますので、そちらを参照ください。
OCI側で HeatWave MySQL を作成します。
ネットワーク構成などを設定してHeatWave MySQLクラスタを作成します。
ハードウェアの構成で「HeatWaveクラスタの有効化」のチェックボックスを チェック することで、HeatWaveクラスタとして利用することが可能となります。
数分待つと、DBシステムが作成完了します。この状態ではまだHeatWaveクラスタは作成中の状態です。
さらにしばらく待つと、次図のようにHeatWaveクラスタもアクティブとなり作成完了した状態になります。
HeatWave MySQL使ってみる
Google Cloudのコンピュートエンジンから、MySQL shellにて HeatWave MySQLに接続します。
HeatWave MySQLの接続タブで接続情報が確認できるため、そのエンドポイントとなるプライベートIPへ直接アクセスしてみます。
※事前にtpch用のオブジェクトの作成などを実施済みです
$ mysqlsh -u root -p -h 192.168.1.62
Please provide the password for 'root@192.168.1.62': **********
Save password for 'root@192.168.1.62'? [Y]es/[N]o/Ne[v]er (default No):
MySQL Shell 8.4.3
Copyright (c) 2016, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.
Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'root@192.168.1.62'
Fetching global names for auto-completion... Press ^C to stop.
Your MySQL connection id is 185 (X protocol)
Server version: 9.1.1-u1-cloud MySQL Enterprise - Cloud
No default schema selected; type \use <schema> to set one.
MySQL 192.168.1.62:33060+ ssl SQL > SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| mysql_audit |
| mysql_option |
| performance_schema |
| sys |
| tpch |
| world |
| world_x |
+--------------------+
9 rows in set (0.0027 sec)
MySQL 192.168.1.62:33060+ ssl SQL > USE tpch;
Default schema set to `tpch`.
Fetching global names, object names from `tpch` for auto-completion... Press ^C to stop.
MySQL 192.168.1.62:33060+ ssl tpch SQL > SHOW TABLES;
+----------------+
| Tables_in_tpch |
+----------------+
| customer |
| lineitem |
| nation |
| orders |
| part |
| partsupp |
| region |
| supplier |
+----------------+
8 rows in set (0.0030 sec)
無事接続できました、HeatWaveの機能が利用できるかも確認してみます。
通常クエリ実行(14.2791sec)に比べるとHeatWave実行(1.5147sec)が大幅に高速化されていることが確認できます。
MySQL 192.168.1.62:33060+ ssl tpch SQL > SELECT /*+ SET_VAR(use_secondary_engine=OFF) */
-> l_returnflag,
-> l_linestatus,
-> SUM(l_quantity) AS sum_qty,
-> SUM(l_extendedprice) AS sum_base_price,
-> SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
-> SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
-> AVG(l_quantity) AS avg_qty,
-> AVG(l_extendedprice) AS avg_price,
-> AVG(l_discount) AS avg_disc,
-> COUNT(*) AS count_order
-> FROM
-> lineitem
-> WHERE
-> l_shipdate <= DATE '1998-12-01' - INTERVAL '90' DAY
-> GROUP BY l_returnflag , l_linestatus
-> ORDER BY l_returnflag , l_linestatus;
+--------------+--------------+-------------+-----------------+-------------------+---------------------+-----------+--------------+----------+-------------+
| l_returnflag | l_linestatus | sum_qty | sum_base_price | sum_disc_price | sum_charge | avg_qty | avg_price | avg_disc | count_order |
+--------------+--------------+-------------+-----------------+-------------------+---------------------+-----------+--------------+----------+-------------+
| A | F | 37734107.00 | 56586554400.73 | 53758257134.8700 | 55909065222.827692 | 25.522006 | 38273.129735 | 0.049985 | 1478493 |
| N | F | 991417.00 | 1487504710.38 | 1413082168.0541 | 1469649223.194375 | 25.516472 | 38284.467761 | 0.050093 | 38854 |
| N | O | 74476040.00 | 111701729697.74 | 106118230307.6056 | 110367043872.497010 | 25.502227 | 38249.117989 | 0.049997 | 2920374 |
| R | F | 37719753.00 | 56568041380.90 | 53741292684.6040 | 55889619119.831932 | 25.505794 | 38250.854626 | 0.050009 | 1478870 |
+--------------+--------------+-------------+-----------------+-------------------+---------------------+-----------+--------------+----------+-------------+
4 rows in set (14.2791 sec)
MySQL 192.168.1.62:33060+ ssl tpch SQL > SELECT /*+ SET_VAR(use_secondary_engine=ON) */
-> l_returnflag,
-> l_linestatus,
-> SUM(l_quantity) AS sum_qty,
-> SUM(l_extendedprice) AS sum_base_price,
-> SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
-> SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
-> AVG(l_quantity) AS avg_qty,
-> AVG(l_extendedprice) AS avg_price,
-> AVG(l_discount) AS avg_disc,
-> COUNT(*) AS count_order
-> FROM
-> lineitem
-> WHERE
-> l_shipdate <= DATE '1998-12-01' - INTERVAL '90' DAY
-> GROUP BY l_returnflag , l_linestatus
-> ORDER BY l_returnflag , l_linestatus;
+--------------+--------------+-------------+-----------------+-------------------+---------------------+-----------+--------------+----------+-------------+
| l_returnflag | l_linestatus | sum_qty | sum_base_price | sum_disc_price | sum_charge | avg_qty | avg_price | avg_disc | count_order |
+--------------+--------------+-------------+-----------------+-------------------+---------------------+-----------+--------------+----------+-------------+
| A | F | 37734107.00 | 56586554400.73 | 53758257134.8700 | 55909065222.827692 | 25.522005 | 38273.129734 | 0.049985 | 1478493 |
| N | F | 991417.00 | 1487504710.38 | 1413082168.0541 | 1469649223.194375 | 25.516471 | 38284.467760 | 0.050093 | 38854 |
| N | O | 74476040.00 | 111701729697.74 | 106118230307.6056 | 110367043872.497010 | 25.502226 | 38249.117988 | 0.049996 | 2920374 |
| R | F | 37719753.00 | 56568041380.90 | 53741292684.6040 | 55889619119.831932 | 25.505793 | 38250.854626 | 0.050009 | 1478870 |
+--------------+--------------+-------------+-----------------+-------------------+---------------------+-----------+--------------+----------+-------------+
4 rows in set (1.5147 sec)
実行計画からも差分を確認することが可能です。
MySQL 192.168.1.62:33060+ ssl tpch SQL > EXPLAIN SELECT /*+ SET_VAR(use_secondary_engine=OFF) */
-> l_returnflag,
-> l_linestatus,
-> SUM(l_quantity) AS sum_qty,
-> SUM(l_extendedprice) AS sum_base_price,
-> SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
-> SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
-> AVG(l_quantity) AS avg_qty,
-> AVG(l_extendedprice) AS avg_price,
-> AVG(l_discount) AS avg_disc,
-> COUNT(*) AS count_order
-> FROM
-> lineitem
-> WHERE
-> l_shipdate <= DATE '1998-12-01' - INTERVAL '90' DAY
-> GROUP BY l_returnflag , l_linestatus
-> ORDER BY l_returnflag , l_linestatus;
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+-------------------+----------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+-------------------+----------------------------------------------+
| 1 | SIMPLE | lineitem | NULL | ALL | NULL | NULL | NULL | NULL | 5845486 | 33.32999801635742 | Using where; Using temporary; Using filesort |
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+-------------------+----------------------------------------------+
1 row in set, 1 warning (0.0033 sec)
MySQL 192.168.1.62:33060+ ssl tpch SQL > EXPLAIN SELECT /*+ SET_VAR(use_secondary_engine=ON) */
-> l_returnflag,
-> l_linestatus,
-> SUM(l_quantity) AS sum_qty,
-> SUM(l_extendedprice) AS sum_base_price,
-> SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
-> SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
-> AVG(l_quantity) AS avg_qty,
-> AVG(l_extendedprice) AS avg_price,
-> AVG(l_discount) AS avg_disc,
-> COUNT(*) AS count_order
-> FROM
-> lineitem
-> WHERE
-> l_shipdate <= DATE '1998-12-01' - INTERVAL '90' DAY
-> GROUP BY l_returnflag , l_linestatus
-> ORDER BY l_returnflag , l_linestatus;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------------------------------------------------+
| 1 | NONE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Using secondary engine RAPID. Use EXPLAIN FORMAT=TREE to show the plan. |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------------------------------------------------+
1 row in set, 1 warning (0.0135 sec)
まとめ
単純にGoogle CloudとOCIを接続して、Google CloudからOCI上のHeatWave MySQLをクエリしているだけなので当然と言えば当然なのですが、Google CloudからもHeatWave MySQLを利用することができました。
HeatWaveからBigQueryやVertex AIとの連携なども視野に入ってくると面白いかも知れません。