Paimon Variant

更新时间:
复制为 MD 格式

Paimon Variant是一种面向半结构化数据的高性能列式存储类型,基于元数据索引与Shredding技术实现高效随机访问与查询下推。本文为您介绍如何在EMR Serverless Spark中通过parse_json写入Variant数据,并使用variant_get进行类型安全、可下推的路径查询。

Variant说明

Variant是一种新型数据类型,用于高效存储和查询半结构化数据(如JSON)。它通过以下特性优化性能:

  • 基于元数据高效随机访问:写入时抽取元数据编码写入,支持高效随机访问。

  • Shredding技术:通过列化技术,减少IO开销,提升查询效率。

  • 标准支持:基于Parquet,兼容主流存储格式。

支持版本

esr-5.1.0 及之后引擎版本支持本文操作。

使用示例

本示例演示如何将JSON String转换为Variant数据类型,并高效查询数据。

写入数据

  1. 进入数据开发页面。

    1. 登录E-MapReduce控制台

    2. 在左侧导航栏,选择EMR Serverless > Spark

    3. Spark页面,单击目标工作空间名称。

    4. EMR Serverless Spark页面,单击左侧导航栏中的数据开发

  2. 新建任务。

    1. 开发目录页签下,单击image图标。

    2. 在新建对话框中,输入名称(例如variant_test_task),类型使用默认的SparkSQL,然后单击确定

  3. 在数据库下拉列表中选择一个数据库,在会话下拉列表中选择一个已启动的会话实例。

    您也可以在下拉列表中选择创建SQL会话,直接创建一个新的会话实例。会话管理更多介绍,请参见管理SQL会话

    说明

    SQL会话建议添加以下Spark配置

    # 读时自动剪裁
    spark.sql.variant.pushVariantIntoScan true
    # 写入时自动shredding
    spark.paimon.variant.inferShreddingSchema true
  4. 拷贝如下代码到新增的Spark SQL页签(variant_test_task)中。单击运行,执行创建的任务。

    --创建表
    CREATE TABLE variant_tbl (id INT, v VARIANT) USING paimon;
    
    --通过parse_jsonJSON String转换为Variant,再写入目标表(否则写入的只是String类型的Variant)
    INSERT INTO variant_tbl
    SELECT
      id,
      CASE
        WHEN id = 0 THEN parse_json('{"age":21,"city":"Beijing"}')
        WHEN id = 1 THEN parse_json('{"age":27}')
        WHEN id = 2 THEN parse_json('{"city":"Beijing", "other":"xxx"}')
        WHEN id = 3 THEN parse_json('{"other":"yyy"}')
        WHEN id = 4 THEN parse_json('{"age":28}')
        WHEN id = 5 THEN parse_json('{"age":27,"city":"Hangzhou"}')
        WHEN id = 6 THEN parse_json('{"age":29,"city":"Beijing"}')
      END AS v
    FROM range(7);
    说明

    除了通过在SQL会话中配置spark.paimon.variant.inferShreddingSchema =true实现写入时自动推断shreddingSchema外,还支持在建表时指定shreddingSchema

    CREATE TABLE variant_tbl (id INT, v VARIANT)
    TBLPROPERTIES
    ('parquet.variant.shreddingSchema' =
    '{"type":"ROW","fields":
      [{"name":"v",
      "type":{"type":"ROW",
      "fields":[{"name":"age","type":"INT"},{"name":"city","type":"STRING"}]}}]}'
    )

查询数据

使用 variant_get 函数从 VARIANT 列中按路径提取强类型字段,语义等价于 get_json_object,但具备类型安全与下推能力。

  • 函数语法

    variant_get(c, path, type)
  • 参数说明

    参数

    说明

    c

    VARIANT 类型列名

    path

    路径

    • 根路径:$

    • 嵌套字段:$.user.name

    • 数组索引:$.items[0].id

    type

    目标数据类型(例如:intstringboolean)。

  • 查询示例

      SELECT
      variant_get(v, '$.age', 'int') AS age,
      variant_get(v, '$.city', 'string') AS city,
      variant_get(v, '$.other', 'string') AS other
    FROM variant_tbl;

    image

使用建议

当需要对查询结果进行进一步处理时,建议通过子查询提前提取字段,以触发列裁剪优化,从而显著减少数据扫描量。

SELECT
  max(age),
  city
FROM (
  SELECT
    variant_get(v, '$.age', 'int') AS age,
    variant_get(v, '$.city', 'string') AS city
  FROM variant_tbl
)
GROUP BY city;