この記事は Accelerating JSON Query Processing using MySQL HeatWave の翻訳版です。

概要

MySQL は効率的で使いやすい JSON クエリー処理をリレーショナルデータベース基盤の中でネイティブに提供します。クラウド版である MySQL HeatWave でも同じ機能が提供されます。開発者は、従来の SQL インターフェイスの利用を選ぶことも、ドキュメントセントリックな CRUD API の利用を選ぶこともできます。Java や .Net などの高度なプログラミング言語で記述されたアプリケーションは、MySQL connector ライブラリを使用して MySQL HeatWave に接続することができ、MySQL Shell は直感的なスクリプティング・インターフェースを提供します。

MySQL HeatWave のドキュメント・ストア・アーキテクチャ

図 1: MySQL HeatWave のドキュメント・ストア・アーキテクチャ

MySQL HeatWave に近日 JSON データ型のサポートが導入されます(訳者註: 本機能は 2023 年 10 月に Oracle Cloud World 2023 で紹介されましたが、2023 年 11 月現在まだ GA として公開されていません)。これにより、アプリケーションを変更することも、インデックスを導入することも不要で、JSON データの処理パフォーマンスが大幅に向上します。クエリーの実行時間は大幅に短縮され、アプリケーション全体のパフォーマンスが向上するため、JSON データ構造に大きく依存するアプリケーションが大幅に強化されます。HeatWave の JSON サポートでは、リアルタイム分析、インメモリ圧縮、桁違いのクエリ高速化など、スカラーデータ型と同様の利点が提供されます。

TPCH_JSON_512

MySQL (秒)

HeatWave (秒)

HeatWave での高速化

単純な検索クエリー

5200

240

20 倍

集計クエリ

5500

250

22 倍

大規模な結合クエリー

10 時間以上

300

144 倍

MySQL と比較すると HeatWave での JSON データ処理は、単純な検索クエリーと集計クエリーは 20 倍速く、大規模な結合を伴うクエリーは 144 倍速い結果が出ています。

HeatWave でのネイティブな JSON データ対応

HeatWaveはインメモリで動作するクエリー・アクセラレータで、MySQL InnoDB に格納されたデータは Hybrid-Columnar 形式に変換されて、HeatWave ノードのメモリにも格納されます。

JSON データを効率的に格納し処理するために、HeatWave は JSON のバイナリ圧縮表現である独自のネイティブ JSON データ型フォーマットを採用しています。JSON カラムは標準カラムと同様に管理され、Heatwave メモリに Hybrid-Columnar 表現で格納されます。同様に、MySQL に保存された JSON データの更新は、ユーザーが介入しなくとも自動的に HeatWave ノードに伝わります。クエリの処理中、JSON への演算は JSON データ構造の圧縮バイナリ表現に対して直接実行されます。

現在、HeatWave では以下の JSON 関数/演算子がサポートされています:

#

関数/演算子

説明

1

column->path

パスを評価した後の JSON カラムの値を返す; JSON_EXTRACT() の結果と同じ

2

column->>path

JSON カラムからパスを評価し、結果をアンクォートした後の値を返す; JSON_UNQUOTE(JSON_EXTRACT()) の結果と同じ

3

JSON_ARRAY()

JSON 配列を作成

4

JSON_DEPT()

JSON ドキュメントの最大深度

5

JSON_EXTRACT()

JSON ドキュメントからデータを返す

6

JSON_LENGTH()

JSON ドキュメント内の要素の数

7

JSON_OBJECT()

JSON オブジェクトを作成

8

JSON_UNQUOTE()

JSON の値をアンクォート

クエリーはサポートされている JSON 関数を使用し、その他のサポートされている SQL 構造はクエリーを高速化するために HeatWave に処理が移譲されます。

例: MySQL Shell で JavaScript を 使って JSON クエリーを実行

ここの例では、1GB の TPC-H ベンチマークデータとスキーマを、TPC-H の全テーブルの各行を JSON ドキュメントに変換することで、JSON データとフォーマットに変換します。このデータセットを MySQL HeatWave インスタンスにロードします。

LINEITEM テーブルは LINEITEM_JSON テーブルに変換されます。このテーブルの各行は JSON ドキュメントで、そのフィールドは元の LINEITEM テーブルのカラムです。

図 2: LINEITEM テーブルは LINEITEM_JSON テーブルに変換されます。このテーブルの各行は JSON ドキュメントで、そのフィールドは元の LINEITEM テーブルのカラムです。

MySQL Shell で MySQL X-プロトコルを使ってクエリーを実行するには:

  1. MySQL HeatWaveインスタンスに接続する

const session = mysqlx.getSession({ host: ‘heatwave.sub11071646451.demovcn.oraclevcn.com’, user: ‘admin’, port: ‘33060’})

const query = session.sql(“set use_secondary_engine=ON;”).execute();

const schema = session.getSchema(“tpch_1_json”);

  1. X-プロトコルを用いた簡単なクエリーの実行: REGION テーブル内の JSON を NAME フィールドで GROUP BY し、その数を返す

var table_region=schema.getTable(‘REGION_JSON’)

var q1 = table_region.select(“INFO->’$.R_NAME'”).groupBy(“INFO->’$.R_NAME'”).execute().fetchAll();

  1. X-プロトコルを用いた結合クエリーの実行: ある年において、特定割引率の割引を一部廃止した場合の増収額を定量化して示す

session.sql(“USE tpch_1_json”).execute();

var q1=session.sql(“select sum(LINEITEM_JSON.INFO->’$.L_EXTENDEDPRICE’ * LINEITEM_JSON.INFO->’$.L_DISCOUNT’) as revenue from LINEITEM_JSON where LINEITEM_JSON.INFO->’$.L_SHIPDATE’ >= date ‘1994-01-01′ AND LINEITEM_JSON.INFO->’$.L_SHIPDATE’ < date ‘1994-01-01’ + interval ‘1’ year AND LINEITEM_JSON.INFO->’$.L_DISCOUNT’ between 0.06 – 0.01  AND  0.06 + 0.01 AND LINEITEM_JSON.INFO->’$.L_QUANTITY’ < 24;”).execute().fetchAll();

  1. 選択された期間の各注文からの収益と割引の範囲を、JSON_OBJECTを使用してJSON形式で表示

session.sql(“USE tpch_1_json”).execute();

var q1=session.sql(“WITH base_table AS (select CAST(LINEITEM_JSON.INFO->>’$.L_ORDERKEY’ as DOUBLE) as order_key, sum(LINEITEM_JSON.INFO->’$.L_EXTENDEDPRICE’ * LINEITEM_JSON.INFO->’$.L_DISCOUNT’) as revenue_per_order from LINEITEM_JSON where LINEITEM_JSON.INFO->’$.L_SHIPDATE’ >= date ‘1994-01-01′ AND LINEITEM_JSON.INFO->’$.L_SHIPDATE’ < date ‘1994-01-01’ + interval ‘1’ year AND LINEITEM_JSON.INFO->’$.L_DISCOUNT’ between 0.06 – 0.01  AND  0.06 + 0.01 AND LINEITEM_JSON.INFO->’$.L_QUANTITY’ < 24 GROUP BY order_key) select JSON_OBJECT(“order_key”, order_key, “revenue_per_order”, revenue_per_order) FROM base_table;”).execute().fetchAll();

  1. JSON_UNQUOTE を用いるクエリーの例

session.sql(“USE tpch_1_json”).execute();

var q1=session.sql(“select JSON_OBJECT(“order_key”, LINEITEM_JSON.INFO->>’$.L_ORDERKEY’, “discount_per_order”, sum(LINEITEM_JSON.INFO->’$.L_EXTENDEDPRICE’ * LINEITEM_JSON.INFO->’$.L_DISCOUNT’)) as revenue_per_order from LINEITEM_JSON where LINEITEM_JSON.INFO->’$.L_SHIPDATE’ >= date ‘1994-01-01′ AND LINEITEM_JSON.INFO->’$.L_SHIPDATE’ < date ‘1994-01-01’ + interval ‘1’ year AND LINEITEM_JSON.INFO->’$.L_DISCOUNT’ between 0.06 – 0.01  AND  0.06 + 0.01 AND LINEITEM_JSON.INFO->’$.L_QUANTITY’ < 24;LINEITEM_JSON.INFO->’$.L_EXTENDEDPRICE’ GROUP BY LINEITEM_JSON.INFO->>’$.L_ORDERKEY’; “).execute().fetchAll();

まとめ

MySQL は、JSON データを処理する標準 SQL と CRUD API の両インターフェースを提供しているため、開発者は JSON 形式の半構造化データとリレーショナル・データをシームレスに使用するアプリケーションを開発できます。MySQL HeatWave はネイティブな JSON 処理をサポートすることで、JSON クエリを大幅に高速化し、複雑な分析ユースケースで JSON を使用するアプリケーションの開発を可能にします。