OCIチュートリアル
トップページへ戻る

その10 - MySQLで高速分析を体験する

Oracle Cloud Infrastructure(OCI) では、HeatWaveクラスタというデータ分析処理を高速化できるMySQL HeatWave専用のクエリー・アクセラレーターが使用できます。HeatWaveクラスタもMySQL HeatWaveと同じく、Always Freeの対象です。トライアルアカウント作成時に付与されるクレジットでも使用可能です。

このチュートリアルでは、コンソール画面からHeatWaveクラスタ付きのMySQL HeatWaveのDBシステムを構成し、MySQLクライアントからサンプルデータベースを構成してHeatWaveクラスタの持つ性能を確認する手順を説明します。


2025年9月追記
本チュートリアル作成当初のサービス仕様に沿った手順のため MySQL HeatWaveのDBシステム作成完了後に、改めてHeatWaveクラスタを作成する手順となっています。現在はMySQL HeatWaveのDBシステム作成時ハードウェアの構成の項目で、デフォルトでHeatWaveクラスタを作成する設定となっています。


所要時間 : 約40分 (約25分の待ち時間含む)

前提条件 :

  1. Oracle Cloud Infrastructure の環境(無料トライアルでも可) と、管理権限を持つユーザーアカウントがあること
  2. OCIコンソールにアクセスして基本を理解する - Oracle Cloud Infrastructureを使ってみよう(その1) を完了していること
  3. クラウドに仮想ネットワーク(VCN)を作る - Oracle Cloud Infrastructureを使ってみよう(その2) を完了していること
  4. インスタンスを作成する - Oracle Cloud Infrastructureを使ってみよう(その3) を完了していること
  5. クラウドでMySQLデータベースを使う(その9)を完了していること

注意 : チュートリアル内の画面ショットについては Oracle Cloud Infrastructure の現在のコンソール画面と異なっている場合があります

目次:


1. HeatWaveクラスタとは?

MySQLクラスタとはMySQL HeatWaveの拡張機能で、検索処理を高速化できるクエリーアクセラレーターです。HeatWaveクラスタは複数のHeatWaveノードから構成されます。HeatWaveノードはデータ分析/集計に向いたカラムナー(列指向)データベースとして実装されており、インメモリで超並列処理を実現し、分析系のSQLも高速に実行できます。

基本的には今までMySQLで実行していたSQLをそのまま使えます。また、レプリケーションを構成してオンプレミス環境や他社クラウド環境にあるMySQL サーバーからETLを使わずにMySQL HeatWaveにデータを連携し、最新のデータを分析するリアルタイムデータ分析環境を構築することもできます。

2. MySQL HeatWave構成時の注意事項

本チュートリアルで構成するMySQL HeatWaveの構成図は以下のようになります。HeatWaveノードはバックグラウンドで動作するため、アプリケーションからの接続先はMySQL HeatWaveのDBシステム、すなわちMySQLサーバーになります。

また、HeatWaveクラスタをデータ分析用途(OLAP)で使う場合の標準的なシェイプであるHeatWave.512GBの場合、HeatWaveノードの最小台数は1台、最大台数は64台となっています。HeatWaveノードではインメモリでデータを保持し、1台あたり約800GBのデータを保持できます。
(データによってデータの圧縮率も変わってくるため、実際に保持できるデータ量はそれぞれのデータに依存します)

img1.png

3. MySQL HeatWaveの構成(HeatWave用DBシステムの構成)


2025年9月追記
本チュートリアル作成当初のサービス仕様に沿った手順のため MySQL HeatWaveのDBシステム作成完了後に、改めてHeatWaveクラスタを作成する手順となっています。下記は旧来の手順となっていますが、MySQL HeatWaveのDBシステム作成時ハードウェアの構成の項目でデフォルトで選択されている「HeatWaveクラスタの有効化」をそのままとし、DBシステム作成と同時にHeatWaveクラスタを作成する手順が推奨されます。


HeatWaveクラスタを構成する時は、MySQL HeatWaveのDBシステムを構成し、そこにHeatWaveのノードを追加します。

  1. コンソールメニューから データベースMySQL HeatWaveDBシステム を選択します。

    img5.png

  2. MySQL DBシステムの作成 ボタンを押します。この際、左下の リスト範囲 でリソースを作成したいコンパートメントを選択していることを確認してください。ここでは「handson」コンパートメントを使用しています。

    img6.png

  3. 立ち上がった DBシステムの作成 ウィンドウの テンプレートは「開発またはテスト」を選択、 ① DBシステム情報 のステップで、以下の項目を入力します。ハードウェアの構成シェイプ選択ではデフォルトで選択されているMySQL.2を使用します。

    ⚠️注意: スクリーンショットではOCPUのシェイプであるMySQL.HeatWave.VM.Standard.E3を使用していますが、2026年3月13日以降、すべてのOCPUシェイプが使用できなくなります。シェイプを変更する場合はECPUのシェイプを選択してください。Always Freeで利用可能なMySQL.Freeを含めた全てのECPUのシェイプがHeatWaveクラスターをサポートしています。
    ⚠️注意: このチュートリアルの手順通り、DBシステム作成後に別途HeatWaveクラスタを作成する場合は、ハードウェアの構成HeatWaveクラスタの有効化の選択を外してください。

    • 名前 - 任意の名前を入力します。ここでは「HeatWave」と入力しています。
    • 説明 - このDBシステムの説明を入力します。ここでは「ハンズオン用」と入力しています。(入力は任意です)
    • データ・ストレージ・サイズ(GB) - データ用のストレージサイズを入力します。ここでは1000GB確保するために「1000」と入力しています。
    img7.png

    img8.png

    img9.png

  4. ② データベース情報 のステップで、以下の項目を入力し ボタンを押します

    • ユーザー名 - MySQL Databaseの管理者ユーザーのユーザー名を指定します。ここでは「root」と入力しています。(セキュリティの観点からは任意のユーザー名を指定することを推奨します)
    • パスワード - MySQL Databaseの管理者ユーザーのパスワードを指定します。パスワードは8文字から32文字までの長さで、大文字、小文字、数字および特殊文字をそれぞれ1つ以上含める必要があります。
    • パスワードの確認 - パスワードを再入力します。
    • ホスト名 - 任意のホスト名を入力します。ここでは「HeatWave」と入力しています。
    img10.png

  5. ③ バックアップ情報 のステップで、何も変更せずに 作成 ボタンを押します。

    img11.png

  6. DBシステムが作成中になるのでしばらく待ちます。概ね15分程度で作成が完了しステータスがアクティブに変わります。

    img12.png img13.png

  7. ページ左下の リソースエンドポイント をクリックして、ホスト名、IPアドレスを確認しておきます。

    img14.png

4. HeatWaveクラスタの追加

  1. MySQL HeatWaveのDBシステムにHeatWaveクラスタを追加します。画面上部のHeatWaveクラスタの追加 をボタンを押します。

    img15.png

  2. シェイプの選択 ボタンを押します。表示されたウインドウでHeatWaveノード用のシェイプであるHeatWave.32GB を選択し、シェイプの選択 ボタンを押します。元のウインドに戻ってシェイプが変更されていることを確認し、HeatWaveクラスタの追加 ボタンをクリックします。 (既にMySQL HeatWaveにデータをロードしている状態であればここで ノード数の見積もり ボタンを押すことで必要なHeatWaveノード数を見積もることもできます。今回はノード数は1にして次に進みます)

    img16.png

    ⚠️注意: スクリーンショットではOCPUのシェイプであるMySQL.HeatWave.VM.Standard.E3を使用していますが、2026年3月13日以降、すべてのOCPUシェイプが使用できなくなります。シェイプを変更する場合はECPUのシェイプであるHeatWave.32GBまたはHeatWave.512GBを選択してください。

    img17.png

    img18.png

  1. HeatWaveノードが作成中になるのでしばらく待ちます。概ね10分程度でHeatWaveノードが追加されます。
    img19.png img20.png

5. サンプルデータベースの構築

MySQL HeatWaveにサンプルデータベースを構築し、HeatWaveノードへデータをロードします。サンプルデータベースは事前に準備してあるTPC-H用のデータを使って構築します。 (TPC-H用のデータをMySQLにロードできるダンプファイルの形式で用意しているので、そのデータをロードしてサンプルデータベースを構築します。TPC-Hは小売業の売り上げを模した汎用的なデータ分析系のベンチマークで、22本のデータ分析/集計系のSQLが用意されています)

  1. インスタンスを作成する - Oracle Cloud Infrastructureを使ってみよう(その3)で作成したコンピュート・インスタンスに接続し、以下のコマンドを実行してハンズオン用のファイルをダウンロードし、解凍します。解凍後に存在するtpch_dumpフォルダの中に、MySQLにロードできるダンプファイルの形式でTPC-H用データが格納されています。

    実行コマンド(コピー&ペースト用)

    cd /home/opc
    wget https://objectstorage.ap-osaka-1.oraclecloud.com/p/seAq8Kgd4TyUqlv5M5qObMJwvsluhCPyOuHOn1L_t4HQYUle2DV-KdFeK44MS7yQ/n/idazzjlcjqzj/b/workshop/o/heatwave_workshop.zip
    
    unzip heatwave_workshop.zip
    ll
    

    実行例

    $  cd /home/opc
    $  wget https://objectstorage.ap-osaka-1.oraclecloud.com/p/seAq8Kgd4TyUqlv5M5qObMJwvsluhCPyOuHOn1L_t4HQYUle2DV-KdFeK44MS7yQ/n/idazzjlcjqzj/b/workshop/o/heatwave_workshop.zip
    e_workshop.zip
    <略>
    heatwave_workshop.zip  100%[=========================>] 332.24M  39.3MB/s    in 6.9s    
    
    2023-05-19 05:09:02 (48.1 MB/s) - 'heatwave_workshop.zip' saved [348382849/348382849]
    
    $  unzip heatwave_workshop.zip
    Archive:  heatwave_workshop.zip
       creating: tpch_dump/
      inflating: tpch_dump/@.json        
    <略>
    $  ll
    total 340244
    -rw-rw-r--. 1 opc opc 348382849 Oct 23  2021 heatwave_workshop.zip
    drwxr-x---. 2 opc opc      8192 Mar 24  2021 tpch_dump
    -rw-rw-r--. 1 opc opc      3299 Mar 25  2021 tpch_offload.sql
    -rw-rw-r--. 1 opc opc      3497 Jun 11  2021 tpch_queries_mysql.sql
    -rw-rw-r--. 1 opc opc      3496 Jun 11  2021 tpch_queries_rapid.sql
    

  2. MySQL Shellを使ってMySQL HeatWaveに接続し、MySQL Shellのロードダンプユーティリティを使用してTHP-H用のデータをロードします。実際にデータをロードする前に、予行演習オプション(dryRun: true)を指定してエラーが出ないことを確認してから、(dryRun: false)に変えてデータをロードします。

    実行コマンド例(コピー&ペースト用):MySQL HeatWaveへの接続
    ※パスワード、ホストの(MySQL HeatWaveの)IPアドレスは環境に合わせて要修正

    mysqlsh --user=root --password=Oracle.123 --host=<mysql_private_ip_address> --port=3306 --js
    

    実行コマンド例(コピー&ペースト用):データロードの予行演習

    util.loadDump("/home/opc/tpch_dump", {dryRun: true, resetProgress:true, ignoreVersion:true})
    

    実行コマンド例(コピー&ペースト用):データロード

    util.loadDump("/home/opc/tpch_dump", {dryRun: false, resetProgress:true, ignoreVersion:true})
    \quit
    

    実行例

    $ mysqlsh --user=root --password=Oracle.123 --host=HeatWave.sub05190127511.tutorialvcn.oraclevcn.com --port=3306 --js
    MySQL Shell 8.0.33
    <略>
    JS >  util.loadDump("/home/opc/tpch_dump", {dryRun: true, resetProgress:true, ignoreVersion:true})
    Loading DDL and Data from '/home/opc/tpch_dump' using 4 threads.
    Opening dump...
    NOTE: Dump format has version 1.0.2 and was created by an older version of MySQL Shell. If you experience problems loading it, please recreate the dump using the current version of MySQL Shell and try again.
    dryRun enabled, no changes will be made.
    Target is MySQL 8.0.33-u2-cloud (MySQL Database Service). Dump was produced from MySQL 8.0.23-u2-cloud
    WARNING: Destination is a MySQL Database Service instance but the dump was produced without the compatibility option. The 'ignoreVersion' option is enabled, so loading anyway. If this operation fails, create the dump once again with the 'ocimds' option enabled.
    Scanning metadata - done       
    Checking for pre-existing objects...
    Executing common preamble SQL
    Executing DDL - done       
    Executing view DDL - done       
    Starting data load
    Executing common postamble SQL                     
    0% (0 bytes / 1.11 GB), 0.00 B/s, 8 / 8 tables done
    Recreating indexes - done 
    No data loaded.                                    
    0 warnings were reported during the load. 
    
    JS >  util.loadDump("/home/opc/tpch_dump", {dryRun: false, resetProgress:true, ignoreVersion:true})
    Loading DDL and Data from '/home/opc/tpch_dump' using 4 threads.
    Opening dump...
    NOTE: Dump format has version 1.0.2 and was created by an older version of MySQL Shell. If you experience problems loading it, please recreate the dump using the current version of MySQL Shell and try again.
    Target is MySQL 8.0.33-u2-cloud (MySQL Database Service). Dump was produced from MySQL 8.0.23-u2-cloud
    WARNING: Destination is a MySQL Database Service instance but the dump was produced without the compatibility option. The 'ignoreVersion' option is enabled, so loading anyway. If this operation fails, create the dump once again with the 'ocimds' option enabled.
    Scanning metadata - done       
    Checking for pre-existing objects...
    Executing common preamble SQL
    Executing DDL - done       
    Executing view DDL - done       
    Starting data load
    2 thds loading / 100% (1.11 GB / 1.11 GB), 58.24 MB/s, 8 / 8 tables done  
    Recreating indexes - done       
    Executing common postamble SQL                                          
    50 chunks (8.66M rows, 1.11 GB) for 8 tables in 1 schemas were loaded in 17 sec (avg throughput 66.24 MB/s)
    0 warnings were reported during the load.
    JS >  \quit
    Bye!
    

  3. mysqlコマンドラインクライアントでMySQL HeatWaveに接続し、tpchデータベース内にテーブルが作成されていることを確認します。

    実行コマンド例(コピー&ペースト用)

    mysql -u root -p --host=HeatWave.sub05190127511.tutorialvcn.oraclevcn.com
    

    実行コマンド例(コピー&ペースト用)

    SHOW DATABASES;
    USE tpch;
    SHOW TABLES;
    

    実行例

    $ mysql -u root -p --host=HeatWave.sub05190127511.tutorialvcn.oraclevcn.com
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    <略>
    mysql>  SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | tpch               |
    +--------------------+
    5 rows in set (0.00 sec)
    
    mysql>  USE tpch;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql>  SHOW TABLES;
    +----------------+
    | Tables_in_tpch |
    +----------------+
    | customer       |
    | lineitem       |
    | nation         |
    | orders         |
    | part           |
    | partsupp       |
    | region         |
    | supplier       |
    +----------------+
    8 rows in set (0.00 sec)
    

  4. 以下のSQLを実行してMySQL HeatWaveでの実行時間を確認しておきます。このSQLはTPC-Hベンチマークの1つ目のSQLです。この例では、8.49秒かかりました。

    実行コマンド(コピー&ペースト用)

    SELECT
        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;
    

    実行例

    mysql>  SELECT
        ->      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 (8.49 sec)    
    

6. HeatWaveクラスタへのデータロード

HeatWaveクラスタを使用する時には、事前に対象テーブルのデータをMySQL HeatWaveのDBシステムからHeatWaveクラスタにロードする必要があります。HeatWaveクラスタにデータをロードした後は、MySQL HeatWaveのDBシステムでデータを変更すると自動的に変更が伝搬されるため、この作業は新しくテーブルを作成した時や初回のデータロード時にのみ行う必要があります。 (HeatWaveノードを再起動した時は、バックグラウンド処理でオブジェクトストレージ上に保存しているHeatWaveフォーマットのデータを自動的にロードするため、手動での再ロードは不要です。また、MySQL HeatWaveのDBシステムからHeatWaveにロードするよりも高速にデータをロードできます)

  1. ALTER TABLE文を使い、tpchデータベース内のテーブルに対してSECONDARY_ENGINE=RAPID を定義します1

    実行コマンド(コピー&ペースト用)

    ALTER TABLE tpch.customer SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.lineitem SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.nation SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.orders SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.part SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.partsupp SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.region SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.supplier SECONDARY_ENGINE=RAPID;
    

    実行例

    mysql>  ALTER TABLE tpch.customer SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.nation SECONDARY_ENGINE=RAPID;Query OK, 0 rows affected (0.00 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    mysql>  ALTER TABLE tpch.lineitem SECONDARY_ENGINE=RAPID;
    ALTER TABLE tpch.orders SECONDARY_ENGINE=RAPID;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    <略>
    

  2. ALTER TABLE テーブル名 SECONDARY_LOAD; を実行し、データをHeatWaveノードにロードします。

    実行コマンド(コピー&ペースト用)

    ALTER TABLE tpch.customer SECONDARY_LOAD;
    ALTER TABLE tpch.lineitem SECONDARY_LOAD;
    ALTER TABLE tpch.nation SECONDARY_LOAD;
    ALTER TABLE tpch.orders SECONDARY_LOAD;
    ALTER TABLE tpch.part SECONDARY_LOAD;
    ALTER TABLE tpch.partsupp SECONDARY_LOAD;
    ALTER TABLE tpch.region SECONDARY_LOAD;
    ALTER TABLE tpch.supplier SECONDARY_LOAD;
    

    実行例

    mysql>  ALTER TABLE tpch.customer SECONDARY_LOAD;
    Query OK, 0 rows affected (1.25 sec)
    
    mysql>  ALTER TABLE tpch.lineitem SECONDARY_LOAD;
    Query OK, 0 rows affected (22.46 sec)
    <略>
    

    なお、本ハンズオンでは内部の動きを理解するために上記の手順を実行していますが、Auto Parallel Loadユーティリティを使用して、より簡単な操作でより高速にデータをHeatWaveノードにロードすることもできます。その場合は、以下のコマンドを実行します。

    実行コマンド(コピー&ペースト用)

    CALL sys.heatwave_load(JSON_ARRAY("tpch"),NULL);
    

7. HeatWaveクラスタの確認

先ほど実行したSQLを再度実行して、HeatWaveクラスタでの実行時間を確認します。この例では、0.13秒で実行出来ていますので、約65倍高速化されています。この例で検索している対象のデータ量は約900MBとそれほど大きくありませんが、この程度のデータ量でも顕著に性能が向上しています。

実行コマンド(コピー&ペースト用)

SELECT
    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;

実行例

mysql> SELECT
    ->     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 (0.13 sec)

なお、HeatWaveクラスタが使われるSQLかどうかは、EXPLAINで実行計画を取ることで確認出来ます。HeatWaveクラスタが使用される場合は Extra列Using secondary engine RAPID と表示されます。

実行コマンド(コピー&ペースト用)

EXPLAIN SELECT
    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;

実行例

mysql> EXPLAIN SELECT
    ->     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.01 sec)

また、オプティマイザヒントを使うことで、HeatWaveクラスタを使うかどうかを明示的に指定することもできます。ヒント句は以下の3種類あります。

  • SET_VAR(use_secondary_engine=ON) : HeatWaveクラスタを使う。HeatWaveクラスタが使えない場合(HeatWaveノードの停止時、HeatWaveクラスタにデータをロードしていない場合など)や、オプティマイザがHeatWaveクラスタを使わない方が効率的と判断した場合はMySQLサーバーで処理する。
  • SET_VAR(use_secondary_engine=OFF) : HeatWaveクラスタを使わない。
  • SET_VAR(use_secondary_engine=FORCED) : 強制的にHeatWaveクラスタを使う。HeatWaveクラスタが使えない場合はSQLがエラーになる。

ヒント句は以下のように、SELECT句の後にSQL文のコメントとして埋め込んで使用します。SQL文の文法的にはコメントになっているため、スペルミスをするなどでヒント句の指定を間違ってもSQLとしてはエラーにならないので注意して下さい。("Unresolved name 'XXXXX' for SET_VAR hint" という警告は発生します)

SELECT /*+ SET_VAR(use_secondary_engine=ON) */ l_returnflag, l_linestatus, <略>
SELECT /*+ SET_VAR(use_secondary_engine=OFF) */ l_returnflag, l_linestatus, <略>
SELECT /*+ SET_VAR(use_secondary_engine=FORCED) */ l_returnflag, l_linestatus, <略>

これで、この章の作業は終了です。

この章ではHeatWaveクラスタを構成し、サンプルデータベースを構築してMySQLサーバーで処理を行った場合とのと性能比較をしました。サンプルデータベースの分析/集計対象データは約900MBとそれほど大きなサイズではありません。また、512GBのメモリを搭載したシェイプのHeatWaveノードも1ノードで構成していますが、それでも約65倍の性能向上が確認出来ています。HeatWaveノードの数を増やすとより性能を向上させられますし、分析/集計対象のデータ量が増えたりSQLが複雑になるとより性能差が出る可能性もあります2。是非、分析/集計業務で使用しているデータを対象にしてテストしてみて下さい。


  1. HeatWaveの根幹をなす技術はOracle社の研究開発部門であるOracle LabsのProject RAPIDの成果を活用しているため、RAPIDという名称が使われています。 ↩︎

  2. HeatWave(旧名称:MySQL Database Service Analytics Engine)リリース時のプレスリリースでは、「分析クエリのためのMySQLのパフォーマンスを400倍向上させます」と案内されています。こちらはTPC-Hのベンチマークを用いて、400GBのデータを対象にしてテストを行った結果です。また、Amazon Redshift、Amazon Auroraとの比較も行っています。これらのベンチマークの結果や再現手順をこちらで案内しています。 ↩︎