Delta外表(XIHE SQL)

更新时间:
复制 MD 格式

AnalyticDB for MySQLXIHE引擎支持通过外部表(EXTERNAL TABLE)方式查询OSS上已有的Apache Delta Lake表。注册外部表后,您可以使用标准SQL查询Delta表的最新快照数据,并利用分区裁剪和列裁剪优化查询性能。本文介绍通过XIHE SQL查询Delta表的方法。

重要

XIHE引擎当前仅支持查询已有Delta Lake表,不支持通过XIHE SQL写入Delta表。如需对Delta表执行写入操作,请使用Spark SQL引擎,详见读写Delta外表

支持能力概览

能力

支持状态

查询已有Delta

支持

Delta reader v1 / v3

支持

Parquet数据文件

支持

列裁剪

支持

复杂类型读取(ARRAY / MAP)

支持

分区表读取

支持

分区裁剪

支持

Delta log统计信息

支持

Deletion Vector读取

支持

JOIN / 聚合 / 排序

支持

INSERT / UPDATE / DELETE / MERGE

不支持

前提条件

  • 集群的产品系列为企业版、基础版或湖仓版。

  • 集群的内核版本为3.2.8及以上版本。

  • 已创建外部数据库。创建方法请参见CREATE EXTERNAL DATABASE

  • OSS上已存在由Spark、FlinkDatabricks等引擎创建的Delta表目录(包含_delta_log)。

建表

语法

CREATE EXTERNAL TABLE [IF NOT EXISTS] <db>.<table> (
    <col1>  <type1>,
    <col2>  <type2>,
    ...
)
STORED AS DELTA
LOCATION '<delta_table_location>';

子句

必填

说明

STORED AS DELTA

声明外部表格式为Delta Lake。

LOCATION

Delta表根目录的OSS路径(包含_delta_log的目录)。不能指向_delta_log本身或分区子目录。

说明

LOCATION指向的目录下已经存在非空_delta_log时,外表注册后会从_delta_log读取真实Schema和文件列表。DDL中的字段建议与底层Delta Schema保持一致,便于元数据展示和问题排查;最终查询Schema_delta_log为准,类型不匹配可能导致查询失败。注册成功后,可使用DESCRIBE查看实际读取到的Delta Schema。

建表示例

-- 创建外部数据库
CREATE EXTERNAL DATABASE IF NOT EXISTS ext_delta_db;

-- 注册Delta外部表
CREATE EXTERNAL TABLE ext_delta_db.delta_orders (
    order_id     BIGINT,
    user_id      BIGINT,
    order_status STRING,
    total_price  DECIMAL(18, 2),
    order_date   DATE
)
STORED AS DELTA
LOCATION 'oss://<YOUR-BUCKET>/warehouse/delta_orders/';

其他DDL操作

-- 查看列结构
DESCRIBE ext_delta_db.delta_orders;

-- 删除外部表
DROP TABLE IF EXISTS ext_delta_db.delta_orders;
说明

DROP TABLE仅删除AnalyticDB中的外部表定义,不删除OSS上的Delta表目录和数据文件。

查询数据

基本查询

查询时默认读取最新快照(Snapshot),保证一次查询中数据一致性。

-- 查询全表
SELECT * FROM ext_delta_db.delta_orders LIMIT 10;

-- 聚合查询
SELECT order_status, COUNT(*) AS order_count, SUM(total_price) AS total
FROM ext_delta_db.delta_orders
GROUP BY order_status;

-- 条件过滤
SELECT order_id, order_status, total_price
FROM ext_delta_db.delta_orders
WHERE order_status IN ('PAID', 'SHIPPED') AND total_price >= 100
ORDER BY total_price DESC;

分区裁剪

Delta表的分区信息来自_delta_log中的元数据和AddFile记录。对分区列添加过滤条件时,引擎基于Delta log中的partition values自动裁剪不相关的分区,减少需要扫描的数据文件:

-- 单值过滤
SELECT * FROM ext_delta_db.delta_orders
WHERE order_date = DATE '2026-06-11';

-- 范围过滤
SELECT order_date, COUNT(*) AS cnt, SUM(total_price) AS total
FROM ext_delta_db.delta_orders
WHERE order_date >= DATE '2026-06-01' AND order_date < DATE '2026-07-01'
GROUP BY order_date;
说明

注册外部表时不需要在DDL中声明PARTITIONED BY,分区信息自动从_delta_log读取。

当前分区裁剪主要覆盖布尔、整数、浮点、字符串、二进制、日期和时间戳等常见分区列类型。Decimal分区列可以读取,但作为过滤条件时不建议依赖分区裁剪。

列裁剪与谓词下推

读取Parquet文件时,引擎只请求查询需要的列;对于结构化字段,符合条件的子字段也可以进入Parquet读取路径。查询规划时会保留未完全下推的普通列过滤条件,由执行引擎继续过滤结果。

-- 仅读取order_id和total_price两列
SELECT order_id, total_price
FROM ext_delta_db.delta_orders
WHERE total_price BETWEEN 100 AND 500;

统计信息

Delta log中包含文件级统计信息时,Delta外表可以读取numRecords、min/max、nullCount等信息,用于优化器的行数和列统计估算。

如果Delta log中没有统计信息,或者文件数量超过统计扫描限制,统计信息可能退化为未知或基于文件大小估算。该能力影响执行计划选择,不改变查询结果语义。

JOIN与聚合

Delta外表可以参与标准XIHE SQL查询,包括JOIN、聚合、排序和窗口函数。JOIN策略由XIHE查询优化器决定。

-- Delta外表与其他表JOIN
SELECT o.order_id, o.total_price, u.user_name
FROM ext_delta_db.delta_orders o
JOIN dim_db.users u ON o.user_id = u.user_id
WHERE o.order_date = DATE '2026-06-11';

支持的数据类型

Delta类型

查询侧类型

说明

BOOLEAN

BOOLEAN

布尔类型

BYTE / SHORT / INTEGER / LONG

TINYINT / SMALLINT / INT / BIGINT

整数类型

FLOAT / DOUBLE

FLOAT / DOUBLE

浮点类型

DECIMAL

DECIMAL(p, s)

定点数

STRING

STRING / VARCHAR

字符串类型

BINARY

VARBINARY

二进制

DATE

DATE

日期

TIMESTAMP / TIMESTAMP_NTZ

TIMESTAMP

时间戳。TIMESTAMP_NTZ(无时区)按TIMESTAMP读取

ARRAY

ARRAY<type>

数组

MAP

MAP<key_type, value_type>

映射

使用限制

  • Delta外表以查询已有Delta表为主,表结构、分区和快照由_delta_log维护。

  • 当前仅支持查询已有Delta表,不支持通过XIHE SQL执行INSERTUPDATEDELETEMERGE操作。

  • 仅支持底层数据格式为ParquetDelta表,非Parquet格式不支持。

  • 支持读取启用了Deletion VectorDelta表,查询时自动应用删除标记。

  • LOCATION必须指向Delta表根目录(包含_delta_log的目录),不能指向_delta_log目录本身或分区子目录。

  • 外部表DDL中的字段建议与底层Delta Schema保持一致。最终查询Schema_delta_log为准,类型不匹配可能导致查询失败。

  • DROP TABLE仅删除AnalyticDB中的外部表定义,不删除OSS上的Delta表目录和数据文件。

  • ALTER TABLE仅修改AnalyticDB中的外部表定义,不影响底层Delta Schema。查询Schema始终以_delta_log为准。如需变更Delta Schema,请在上游生产链路中完成。

  • Decimal类型的分区列可以读取,但作为过滤条件时分区裁剪效果可能有限。

  • 当前不支持通过外表DDL创建新的Delta分区表;已有分区表可以读取和分区裁剪。

  • 复杂类型(ARRAY、MAP)可以读取;复杂类型上的复杂过滤条件通常由执行引擎完成过滤。

  • 如果Delta log Schema与底层Parquet文件Schema不一致,查询阶段可能报Schema mismatch错误。

  • 分区值来自Delta log的字符串表示,分区列类型不符合预期时可能在分区值转换阶段报错。