HeatWave MySQL が 9.0 で Auto Scheduling を実装したことでクエリの実行時間がかえって延びた件

## この記事は何？

去る 2025/4/17 に、HeatWave ユーザーコミュニティである **[HeatWavejp（MySQL HeatWave Japan User Group）](https://heatwavejp.connpass.com/)** の 2 周年記念 LT 大会があり、その中で [HeatWave をレプリカに使うケースでのレプリケーションラグ](https://www.docswell.com/s/hmatsu47/KXENLN-inbound-replication-lag)について発表を行いました。

https://heatwavejp.connpass.com/event/349599/

<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/KXENLN/embed" data-aspect="0.5625"></script><div class="docswell-link"><a href="https://www.docswell.com/s/hmatsu47/KXENLN-inbound-replication-lag">HeatWave on AWS のインバウンドレプリケーションで HeatWave エンジン有効時のレプリケーションラグを確認してみた！ by @hmatsu47</a></div>

発表に向けた調査（というか正確には「プロダクト利用に向けた調査をまとめて、ついでに LT で発表した」のですが）の中で、発表の本題とは別に HeatWave MySQL 8.4.3 と 9.0.0 以降での動作の違いについても検証していて気になることがあったので、LT とは別に記事としてまとめました。

## HeatWave（HeatWave MySQL）とは？

途中のリブランディングで混乱していますが（笑）、

- **HeatWave :**
  - Oracle Cloud が提供する、オープンソース RDBMS（MySQL）を中心としたマネージドサービスの総称
  - on OCI と on AWS がある
  - 分析・集計に強い列指向エンジン（HeatWave Cluster）や、AI/ML 系のサービスと統合されている
- **HeatWave MySQL :**
  - HeatWave サービスに含まれる MySQL データベースのマネージドサービス

です。

:::note
文脈によって、**HeatWave MySQL** は MySQL データベースにオプションの列指向エンジン（HeatWave Cluster）を追加した状態のことを指す場合もあります。
この記事でも概ね HeatWave Cluster を追加した状態のことを指して「HeatWave MySQL」と記しています。
:::

詳細は、（ちょっと古いのでブランド名やサポートする機能・仕様が一部現在と異なりますが）以下の記事や、

https://qiita.com/hmatsu47/items/8f202eef64ea57e7d948

https://qiita.com/hmatsu47/items/0979f877ad596cf3cf67

2025/2/22 開催の [PHP カンファレンス名古屋 2025](https://phpcon.nagoya/2025/) での[発表スライド 46 ページ](https://www.docswell.com/s/hmatsu47/Z3GL92-2025-02-07-144215#p46)以降をご確認ください。

<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/Z3GL92/embed" data-aspect="0.5625"></script><div class="docswell-link"><a href="https://www.docswell.com/s/hmatsu47/Z3GL92-2025-02-07-144215#p46">さいきんの MySQL との付き合い方 〜 MySQL 8.0 より後の世界へようこそ 〜 by @hmatsu47</a></div>

## HeatWave MySQL の Auto Scheduling

厳密には **HeatWave MySQL の Auto Scheduling** というよりは **HeatWave MySQL が HeatWave Cluster にクエリ処理を実行させる際の Auto Scheduling 機能** といったほうが誤解がなさそうですが（ブランドがややこしいので説明もややこしい…）、この機能は HeatWave MySQL 9.0.0 で実装されました。

https://dev.mysql.com/doc/heatwave/en/mys-hw-query-priority-queue.html

↑の説明によると、
> HeatWave MySQL uses a workload-aware, priority-based, automated scheduling mechanism to schedule concurrently issued queries for execution. The scheduling mechanism prioritizes short-running queries but considers wait time in the queue so that costlier queries are eventually scheduled for execution. This scheduling approach reduces query execution wait times overall.

日本語に訳す（by Google）と、

> HeatWave MySQL は、ワークロードを考慮した優先度ベースの自動スケジューリングメカニズムを使用して、同時に発行されたクエリの実行をスケジュールします。このスケジューリングメカニズムは、実行時間の短いクエリを優先しますが、キュー内の待機時間も考慮するため、最終的にはコストの高いクエリが実行スケジュールされます。このスケジューリングアプローチにより、クエリ実行の待機時間が全体的に短縮されます。

だそうです。

HeatWave MySQL 8.4 以前は、HeatWave Cluster でクエリ処理を実行させる場合、

- 同時に処理できるのは 1 つのクエリだけ
- クエリ処理が実行中に新たにクエリ処理がリクエストされた場合はキューにためられて順番に実行される

という仕様でした。

そして 9.0 からは HeatWave Cluster が持つ計算リソースを（おそらく）時分割で割り当てることによってクエリを並行して実行できるようになった、という話です。

:::note
**2025/4/24 追記：**
個人的に Oracle Cloud のパートナーさんから「並列処理できるようになった」と聞いていたので当初「並列」と書きましたが、公式ドキュメントからは「並行」のように読み取れるので、「並行」に表現を改めました。
:::

## Auto Scheduling の問題点

私は普段 on OCI ではなく on AWS で検証しているので、今回も on AWS で試したときの話です。

:::note warn
- 事情により検証に使ったデータとクエリ（SQL 文）は非公開です。
- データとクエリによっては結果が異なる場合があります。
:::

[先ほどの HeatWavejp 発表スライド 8 ページ](https://www.docswell.com/s/hmatsu47/KXENLN-inbound-replication-lag#p8) に記した HeatWave MySQL 8.4.3 + HeatWave Cluster の環境で、とある集計クエリを流したところ、単発では 2.78 秒掛かりました。

`mysql`コマンドを開いたコンソールを 2 つ使って同じクエリを立て続けに流そうとすると、先に流したほうは（後から流したほうの影響を受けず）約 2.78 秒、後から流したほうは先に流したクエリの待ち時間＋約 2.78 秒掛かりました。

ここまでは想定どおりでした。

そして、同じデータベースを 9.0.1 にバージョンアップしてクエリを実行してみたところ、

- 先に流したほうが、後から流したほうよりも後に結果が返ることがある
- 先に流したほう＋後から流したほうのクエリの合計実行時間が、2.78 × 2 = 5.56 秒よりも明らかに長い

のがわかりました。

さらに（検証時点で最新の）9.2.2 にバージョンアップして実行してみても結果は変わらず。

**並行処理できるようになったのは良いけれど、クエリの実行時間そのものを合計すると明らかに長く（実行が遅く）なってしまった**のです。

そして **HeatWave MySQL 9.0.0 以降では Auto Scheduling を無効にできない**のも問題です。

## あらためて比較検証

というわけで、同じ「単発で 2.78 秒掛かるクエリ」を使って検証です。

環境は HeatWave MySQL 8.4.3 と 9.2.2 を用意します。シェイプのサイズやデータの内容などは同じ状態です。

- 4 スレッドで 1 スレッドあたり 6 回同じクエリを連続実行
- スレッドごとに 0.75 秒ずつ開始時間を遅延させる

結果は以下のとおりです。

![hwc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/f0b234f5-289f-42d9-8f46-4ff91170847f.png)

:::note
横幅の関係で Markdown での表組で綺麗に表示するのが難しいので画像形式で貼り付けました。字が小さく読みづらくてごめんなさい。
（表の画像をクリックして拡大してください）
:::

8.4.3 のほうは先の説明のとおりにクエリが順番に直列で実行されています。開始・完了の逆転も発生していません。

時間差で開始・終了している 1 回目と 6 回目を除くと、**所要時間（クエリの実行時間＋先にキューに入っているクエリの実行待ち時間）は平均 11.105 秒であり、これは 2.78 × 4 = 11.12 秒とほぼ同じ**です。

一方で 9.2.2 のほうは、同様に 1 回目と 6 回目を除いた**所要時間（クエリの実行時間）は平均 13.559 秒であり、13.559 - 11.12 = 2.439 秒のオーバーヘッド**があります。

さらに見ていくと、3 回目あたりから

- 開始時間と終了時間の逆転

が見られるようになるとともに、

- 各実行回の終了時間が全スレッドでほぼ同じ

になっています。

スケジューラーが（キューに入った）どのクエリのタスク処理を優先するか？の判定アルゴリズムや、（並行処理以外に並列処理部分があれば、その際に使用する）共有リソースのロック範囲あたりに問題がありそうな印象です。

## というわけで

**最低限、Auto Scheduling が無効化できるようになってくれないかな？** と思っているところなのでした。

:::note
中の人向けにフィードバックはしているのですが、採用されるか（そもそも可能なのか）はわかりません。
:::