[Preview] Flat JSON
このトピックでは、Flat JSON 機能の基本概念とその使用方法について紹介します。
v2.2.0 以降、StarRocks は JSON データの保存をサポートしており、より柔軟なデータストレージが可能です。しかし、ほとんどのクエリシナリオでは、ユーザーは完全な JSON データではなく、指定されたパスの JSON データにのみアクセスします。次の例では、必須フィールドを固定フィールドとして保存し、ビジネスに応じて頻繁に変更されるフィールドを JSON データとしてパッケージ化しています。
SELECT
time,
event,
user,
get_json_string(remain_json, "$.from_system"),
get_json_string(remain_json, "$.tag")
FROM logs;
しかし、クエリ中、JSON データのパフォーマンスは INT や STRING などの標準データ型ほど良くありません。その理由は以下の通りです:
- JSON は半構造化データ型であり、各行のデータ構造を保存する必要があります。これにより多くのストレージを占有し、圧縮効率が低くなります。
- JSON データをクエリする際、ランタイムデータに基づいてデータ構造を検出する必要があり、ベクトル化最適化を達成するのが難しくなります。
- JSON データをクエリする際、冗長なフィールドを含む完全な JSON データを読み取る必要があります。
StarRocks は v3.3 で Flat JSON 機能を導入し、JSON データのクエリパフォーマンスを最適化し、JSON の使用コストを削減します。
Flat JSON とは?
Flat JSON の核心原理は、データロード中に JSON データを検出し、JSON データから共通フィールドを標準データ型として抽出して保存することです。クエリ中、これらの共通フィールドを直接クエリすることで、JSON のクエリ速度を加速します。データの例:
1, {"a": 1, "b": 21, "c": 3, "d": 4}
2, {"a": 2, "b": 22, "d": 4}
3, {"a": 3, "b": 23, "d": [1, 2, 3, 4]}
4, {"a": 4, "b": 24, "d": null}
5, {"a": 5, "b": 25, "d": null}
6, {"c": 6, "d": 1}
a
と b
フィールドはほとんどの行に存在し、そのデータ型は似ています(どちらも INT)。したがって、a
と b
フィールドのデータは JSON データから読み取られ、2 つの INT 列として別々に保存されます。これらの 2 つの列に対するクエリが行われる場合、他の列を読み取る必要がなく、計算中の JSON 構造の処理オーバーヘッドを削減します。
使用上の注 意
- 共有なしクラスタは v3.3.0 以降で Flat JSON をサポートします。共有データクラスタは v3.3.3 以降で Flat JSON をサポートします。
- StarRocks のすべてのテーブルタイプは Flat JSON をサポートします。
- Flat JSON は過去の JSON データと互換性があります。Flat JSON が有効になった後、以前にロードされた履歴データは上書きされず、フラット化された JSON データと共存します。
- 新しいデータが書き込まれると、Flat JSON 操作は Compaction を通じて自動的に完了します。
v3.3.0、v3.3.1、および v3.3.2 では:
- データロード中、Flat JSON は共通フィールドを抽出して JSON タイプとして保存することをサポートしますが、型推論はサポートされていません。
- 抽出された列と元の JSON データの両方が保存されます。元のデータが削除されると、抽出されたデータも削除されます。
v3.3.3 以降:
- Flat JSON から抽出された結果は、共通フィールドと予約フィールドに分けられます。すべての JSON スキーマが一貫している場合、予約フィールドは生成されません。
- データロード中、共通フィールドは自動的に BIGINT/LARGEINT/DOUBLE/STRING タイプとして推論されます。認識されないタイプは JSON タイプとして推論されます。予約フィールドは JSON タイプとして保存されます。
- Flat JSON は共通フィールドと予約フィールドのみを保存し、元の JSON データは保存しません。
Flat JSON の使用方法
-
Flat JSON を使用するには、BE 動的パラメータ
enable_json_flat
を有効にする必要があります(デフォルト:false
)。有効にすると、新しくロードされた JSON データが自動的にフラット化されます。curl -XPOST http://<be_host>:<be_http_port>/api/update_config?enable_json_flat=true
-
JSON データをクエリする前に、セッション変数
cbo_prune_json_subfield
を有効にします(デフォルト:false
)。SET cbo_prune_json_subfield = true;