全部产品
Search
文档中心

云原生大数据计算服务 MaxCompute:OBJECT TABLE定义

更新时间:Dec 31, 2025

MaxCompute推出了Object Table功能,该功能支持数仓计算引擎访问数据湖存储中的非结构化数据及其元信息。本文为您介绍Object Table相关的命令语法和示例。

背景信息

许多AI流程环节需要熟悉数据和业务的数仓开发者,利用大数据平台提供的低成本大规模算力对大模型进行数据预处理或非结构化数据处理。这些计算过程及其结果将与数仓或数据湖中的数据进行交互。

使用SQL处理非结构化数据存在以下问题。

  • 大数据SQL引擎在读取对象存储文件时并不感知对象的大小,因此缺乏依据来优化执行计划。这使得控制并发或自动启动合适的并发变得困难。同时,由于无法有效下推过滤条件,在数据倾斜的情况下,无法充分发挥算力的优势。

  • 对象存储的元信息读取性能不足,每次查询均需远程访问存储服务,导致延时较高。

  • 只能在UDTF中以单进程串行方式获取对象存储的文件列表,导致数据读取性能较差。

  • 需要在用户自定义函数(UDF)中自主实现权限打通的逻辑,并且需要实现UDF与存储服务等之间的网络连接逻辑。

  • UDF在非结构化数据处理方面的能力不足,传统数据仓库缺乏灵活且安全的自定义镜像上传功能,同时也缺乏UDF的安全运行环境。此外,远程调用需要与分布式计算服务进行并发对接。

功能说明

MaxCompute推出了Object Table功能,该功能支持数仓计算引擎访问数据湖存储中的非结构化数据及其元信息,具备以下能力:

  • 支持引擎以表的形式读取OSS文件元信息。

  • 基于Metadata Table能力,以版本化方式缓存OSS文件的各种元信息,后续SQL引擎能基于Metadata Table实现有效的查询优化,包括数据过滤和条件下推等功能。

  • 基于内置文档函数以多种方式读取非结构化数据文件内容。

  • MaxCompute SQL引擎基于Object Table元信息进行并发切分,启动大规模分布式计算能力,以提高数据读取和处理的效率。

  • 支持用户上传自定义镜像构建UDF,并处理引擎读取的非结构化数据。

  • 支持引擎处理非结构化数据,生成结构化数据结果并将其写入数据仓库的内部表和外部表,后续支持生成非结构化数据结果,并通过Object Table写回对象存储服务。

  • 支持Python生态系统的Maxframe引擎。

使用限制

  • MaxCompute项目需要支持Schema功能,详情请参见Schema功能开启

  • MaxCompute需要支持2.0数据类型系统。

  • Object Table暂不支持分区。

费用说明

  • Object Table是OSS上文件元信息的集合,因此会对刷新存入Object Table的元数据收取存储费用,详情请参见存储费用。由于OSS上的文件没有存储在MaxCompute内部,MaxCompute不收取存储费用,具体存储和访问数据的费用由OSS存储服务收取,详情请参见OSS存储费用

  • 在刷新OSS元信息的抽取任务中,扫描的每个文件的inputsize是一个与元信息相关的值,而与文件的实际大小无关。因此,刷新计算任务的整体费用与OSS上对应文件的实际大小无关,而是与文件数量相关。详情请参见SQL外部表计费

  • 使用Object Table及其相关元数据进行OSS非结构化数据的分析与提取,并进行相应处理,会产生计算费用。

    • 在按量付费模式下,对Object Table的元数据分析按照内表进行计费,请参见SQL标准计费。而对OSS非结构化数据的内容进行处理则按照外表进行计费,请参见SQL外部表计费

    • 在包年包月付费模式下,均使用包年包月的预付费资源,请参见计算费用(包年包月)

创建OBJECT TABLE

语法

CREATE OBJECT TABLE [IF NOT EXISTS] <objecttable_name> 
WITH SERDEPROPERTIES ('<key>' = '<value>') 
LOCATION '<location>' 
[TBLPROPERTIES ('<key>' = '<value>')] 
[COMMENT '<comment>'] 
;
说明
  • Object Table需要在内部项目支持Schema模式下使用,同时开启Schema语法开关。

  • Object Table不需要定义列,元数据信息列由系统提供。

参数说明

参数

是否必填

说明

objecttable_name

必填。

表名。

SERDEPROPERTIES ('<key>'='<value>')

必填。

支持填写RAM角色认证信息。不填则默认使用当前阿里云账号(主账号)的名为AliyunODPSDefaultRole的RAM角色访问OSS。

例如:'odps.properties.rolearn'='acs:ram::uid:role/aliyunodpsdefaultrole'

使用前,请确保已完成AliyunODPSDefaultRole一键授权),将当前云账号的OSS资源通过STS Token的方式授权给MaxCompute项目直接访问。

说明

当MaxCompute的ProjectOwner为OSS云账号时,才可以执行一键授权。

location

必填。

  • Object Table映射的OSS对象存储的路径。格式为oss://<oss_endpoint>/<Bucket名称>/<OSS目录名称>/。例如:oss://oss-cn-hangzhou-internal.aliyuncs.com/odps-external-****/ottest/

  • Object Table会抽取目录下文件的元信息。

  • 其中oss_endpoint的获取方式如下:

    • 登录对象存储OSS控制台

    • Bucket 列表页面,单击目标Bucket 名称,进入文件列表页面。

    • 概览页的访问端口区域,获取ECS 的经典网络访问(内网)对应的Endpoint(地域节点)

TBLPROPERTIES ('<key>'='<value>')

可选。

metadata.cache.mode:缓存刷新模式设定。

  • manual表示手动触发(默认)

  • periodic表示周期性触发,需配合metadata.staleness.seconds刷新周期参数使用。

    • metadata.staleness.seconds:刷新周期参数。取值范围为[1, 604800],表示1秒到1周范围。该参数并非强制性保障,调度器将尽可能按照该参数进行执行。

comment

可选。

表注释内容。

示例

SET odps.namespace.schema=true; 
CREATE OBJECT TABLE ot_demo_day 
WITH serdeproperties ( 
 'odps.properties.rolearn'='acs:ram::xxxxxx:role/aliyunodpsdefaultrole') 
LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/odps-external-****/ottest/';

查看OBJECT TABLE属性

语法

DESC <objecttable_name>

参数说明

objecttable_name:必填,表名。

示例

DESC ot_demo_day; 

返回结果如下。

+------------------------------------------------------------------------------------+
| Owner:                    ALIYUN$****@test.aliyunid.com                        |
| Project:                  test_objecttable                                         |
| Schema:                   default                                                  |
| TableComment:                                                                      |
+------------------------------------------------------------------------------------+
| CreateTime:               2024-09-02 20:01:56                                      |
| LastDDLTime:              2024-09-02 20:01:56                                      |
| LastModifiedTime:         2024-09-02 20:01:56                                      |
+------------------------------------------------------------------------------------+
| InternalTable: YES      | Size: 0                                                  |
+------------------------------------------------------------------------------------+
| Native Columns:                                                                    |
+------------------------------------------------------------------------------------+
| Field           | Type       | Label | Comment                                     |
+------------------------------------------------------------------------------------+
| key             | varchar(2048) |       | The name of the object.                     |
| size            | bigint     |       | The size of the returned object in bytes.   |
| type            | varchar(32) |       | The type of the object and valid values: Normal, Multipart, Appendable, and Symlink. |
| last_modified   | timestamp  |       | The last modified time of the object.       |
| storage_class   | varchar(32) |       | The storage class of the object.            |
| etag            | varchar(64) |       | The entity tag (ETag). When an object is created, an ETag is created to identify the content of the object. |
| restore_info    | varchar(256) |       | The restoration status of the object.       |
| owner_id        | bigint     |       | The ID of the bucket owner.                 |
| owner_display_name | varchar(256) |       | The display name of the bucket owner.       |
+------------------------------------------------------------------------------------+

返回结果部分列名说明。

列名

类型说明

是否支持NULL

说明

key

VARCHAR(2048)

原生长度约束为1023。

预留OSS对象命名规范和命名示例

False

对象在Object Table中的相对路径名。

size

BIGINT

False

对象的大小,单位为字节。

type

VARCHAR(32)

False

对象在OSS侧的文件类型:Normal、Multipart、Appendable和Symlink。

last_modified

TIMESTAMP_NTZ

False

对象在OSS上的数据最后变更时间。

storage_class

VARCHAR(32)

False

对象在OSS上的存储类型。具体类型请参见存储类型

etag

VARCHAR(64)

False

ETag在每个Object生成时创建的实体标记(一个签名信息),用于标识一个Object的内容在前后两次更新过程中是否变化(但不是唯一性标记)。

restore_info

VARCHAR(256)

True

描述一个对象是否被从冷存中恢复,如果是恢复过程中的对象,则有相关的信息描述。

owner_id

BIGINT

True

对象的所有者ID。

owner_display_name

VARCHAR(256)

True

对象的所有者的名称。

查看OBJECT TABLE建表语句

语法

SHOW CREATE TABLE <objecttable_name>;

参数说明

objecttable_name:必填,表名。

示例

SHOW CREATE TABLE ot_demo_day; 

返回结果如下。

CREATE OBJECT TABLE IF NOT EXISTS yunqi_object_****.`default`.ot_demo_day 
WITH SERDEPROPERTIES ( 
  'serialization.format'='1', 
  'odps.properties.rolearn'='acs:ram::139699392458****:role/aliyunodpsdefaultrole') 
LOCATION 
  'oss://oss-cn-hangzhou-internal.aliyuncs.com/odps-external-****/ottest/' 
TBLPROPERTIES ( 
  'last_modified_time'='1731478307', 
  'transient_lastDdlTime'='1731478307', 
  'metadata.cache.mode'='manual', 
  'metadata.staleness.seconds'='3600');

刷新OBJECT TABLE元信息

Object Table的真实对象数据存储于OSS中。在MaxCompute中,对这些对象数据的元信息进行缓存,并基于缓存的元数据执行各种查询和计算。因此,在实际使用Object Table之前,需要对其进行一些缓存更新操作。可以通过手动刷新或在建表时配置周期性刷新参数。

说明

无论是手动刷新还是周期性刷新,都是全量刷新。

手动刷新

每次刷新均为全量元信息同步,您可自主控制刷新的时机与频率。

  • 语法

    ALTER TABLE <objecttable_name> REFRESH METADATA;
  • 参数说明

    objecttable_name:必填,表名。

  • 示例

    ALTER TABLE ot_demo_day REFRESH METADATA;

周期性刷新

如果Object Table映射的OSS目录中的文件经常发生变化,可以按周期刷新元数据。只需要在建表时指定相关参数即可,减少维护的成本。

  • 语法

    SET odps.namespace.schema=true;
    SET odps.sql.type.system.odps2 = true;
    
    CREATE OBJECT TABLE ot_demo_day 
    WITH serdeproperties (
     'odps.properties.rolearn'='acs:ram::xxxxxx:role/aliyunodpsdefaultrole'
    )
    location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/odps-external-****/ottest/'
    tblproperties (
      'metadata.cache.mode' = 'periodic',
      'metadata.staleness.seconds' = '3600'
    );
    
  • 参数说明

    • metadata.staleness.seconds:刷新周期。对于periodic模式来说,必须要指定这个参数,取值范围为[1, 604800],表示1秒到1周范围内。该参数并非强制性保障,调度器将尽可能按照该参数进行执行。

    • metadata.cache.mode:刷新触发方式,有两种选择。

      • periodic:周期性触发。

      • manual:手动触发(默认),您可以自主控制触发时机。

查看刷新任务

可以通过如下命令查看历史的刷新任务状态。

SHOW refresh task history FOR object TABLE <object_table_name>;
  • 参数说明

    • <object_table_name>必须是一个Object Table;

    • 返回值:执行刷新的实例id(InstanceId)、开始时间(CreateTime)、结束时间(EndTime)、执行状态(Status)。

    • 当执行状态(Status)值为Failed时,可通过wait InstanceId;打印log view查看报错明细。

  • 示例

    -- 查看Object Table的历史刷新任务
    SHOW refresh task history for object table ot_demo_day04;
    
    -- 返回结果如下

查询OBJECT TABLE

Object Table获取了OSS目录中文件的元信息,您可以通过查询Object Table明细来浏览这些元信息,也可以使用SQL语句对元信息进行过滤、匹配等计算,包括但不限于Aggregation、Join、Window、Order By、Limit等。

语法

SELECT * FROM <objecttable_name>;

参数说明

objecttable_name:必填,表名。

示例

-- 您可以查询上传至指定OSS对象目录下的数据,若数据量大,您可以查看5条。
SELECT * FROM  ot_demo_day [limit 5];

查询对象内容进行业务计算

查询过程本质上仅针对对象的元信息进行相关计算,并不涉及对象的实际内容。然而,实际的计算过程需要读取对象的真实内容。MaxCompute内置了下载函数,以便用户能够将其集成到实际的计算过程中。

GET_DATA_FROM_OSS函数语法

GET_DATA_FROM_OSS函数用于读取一个对象的部分或全部内容,并以二进制形式返回。

BINARY GET_DATA_FROM_OSS (
  STRING <full_object_table_name>,
  STRING <key> 
  [, BIGINT <offset>]              
  [, BIGINT <length>] 
  [, STRING <object_not_found_policy>] 
)

参数说明

参数

是否必填

数据类型

说明

默认值

full_object_table_name

STRING

三层模型下,完整的OBJECT TABLE路径,包括Project和Schema名称,如project.schema.object_table

如果在建表时选择了RoleARN的认证方式,该参数将协助用户自动生成访问OSS的STS Token。

key

STRING

即被访问对象在该Object Table中的名称。详情请参见查看OBJECT TABLE属性返回结果中的key参数说明。

offset

BIGINT

表示读取对象内容的起始位置,取值大于等于0。

默认为0,即从头开始读取。

length

BIGINT

需要读取的字节数。

默认值为-1,即不限制长度。

object_not_found_policy

STRING

表示缓存数据中存在某个对象的key,但在实际的OSS中该对象已不存在时,MaxCompute返回当前函数调用结果的方式。取值如下:

  • OUTPUT_NULL:不抛出异常,输出为NULL。

  • THROW_EXCEPTION:直接抛出异常,终止当前任务。

  • WARN_AND_NULL:不抛出异常,输出为NULL。同时在SQL Runtime的输出日志中记录该对象不存在的情况。如果大量对象出现这种不一致的情况,可能会对整体任务的性能造成一定影响。

默认值为OUTPUT_NULL。

示例一

如果需要将GET_DATA_FROM_OSS函数的结果输出为STRING类型,可以嵌套一层STRING函数。

SELECT STRING(
  GET_DATA_FROM_OSS('<project_name>.default.ot_demo_day', key, 0, -1, 'OUTPUT_NULL')
) 
FROM ot_demo_day;

示例二

读取Object Table的全部内容,并以二进制形式返回。默认Object Table的完整路径为<project_name>.default.ot_demo_day,不同参数组合方式如下。

-- 最完整形式。
SELECT GET_DATA_FROM_OSS('<project_name>.default.ot_demo_day', key, 0, -1, 'OUTPUT_NULL') FROM ot_demo_day;

-- 以下写法均与get_data_from_oss('<project_name>.default.ot_demo_day', key, 0, -1, 'OUTPUT_NULL')等价。
SELECT GET_DATA_FROM_OSS('<project_name>.default.ot_demo_day', key) FROM ot_demo_day;

SELECT GET_DATA_FROM_OSS('<project_name>.default.ot_demo_day', key, 0) FROM ot_demo_day;

SELECT GET_DATA_FROM_OSS('<project_name>.default.ot_demo_day', key, 0, -1) FROM ot_demo_day;

SELECT GET_DATA_FROM_OSS('<project_name>.default.ot_demo_day', key, 'OUTPUT_NULL') FROM ot_demo_day;

SELECT GET_DATA_FROM_OSS('<project_name>.default.ot_demo_day', key, 0, 'OUTPUT_NULL') FROM ot_demo_day;

使用查询优化技术提升性能

默认情况下,在MaxCompute的SQL中访问某张表时,将根据该表的记录行数、记录的字节数以及总的计算资源(受限于用户的配额配置)进行合理且均匀的切片处理。此举旨在为不同的分片提供并行计算能力,从而有效控制并行任务中的长尾问题,提升整体查询性能。

这种切片方式对于需要下载对象表中对象内容以进行内存计算的SQL不太适用,性能表现并不是最佳方案,I/O操作容易成为瓶颈,从而导致长尾问题。考虑以下案例:

key

size

a0000.jpg

10MB

a0001.jpg

10MB

a0002.jpg

10MB

……

……

a1022.jpg

10MB

a1023.jpg

10MB

b.avi

10GB

假设我们仅有两个工作资源可用,按照普通内表的处理方式,以行数或记录字节进行切片,我们可能会切出两个split对象,分别是split1([a0000.jpg ~ a0511.jpg])和split2([a0512.jpg ~ a1023.jpg, b.avi])。实际的split1所需下载的数据量为10 MB * 512 = 5 GB,而split2所需下载的数据量为5 GB + 10 GB=15 GB。因此,split2对应的计算量明显高于split1,导致出现严重的长尾现象。

真正合理的逻辑是:当用户的SQL中存在下载对象的需求时,应尽量根据对象的实际大小进行切片,以最大限度地控制长尾问题。如果用户消费OSS对象数据的逻辑更加耗时,则更需要提供灵活的切片能力。针对上述案例,我们可以拆分出split1:[a0000.jpg ~ a1023.jpg]和split2:[b.avi]两个切片,这两个切片的下载量均为10 GB。

为此,MaxCompute的Object Table提供了这样的能力,并且默认按照对象的实际大小进行切片。该默认值为1GB,用户可根据需要进行调整,粒度可选择KB、MB或GB三个级别。

# 默认为1GB,用户可以自行调整
SET odps.sql.object.table.split.unit.gb = 1;
SELECT get_data_from_oss('project.default.ot_demo_day', key) FROM ot_demo_da WHERE ...


# 或者,用户选择MB级控制,优先级高于GB参数
SET odps.sql.object.table.split.unit.mb = 1;
SELECT get_data_from_oss('project.default.ot_demo_day', key) FROM ot_demo_da WHERE ...


# 或者,用户选择KB级控制,优先级高于GB、MB参数
SET odps.sql.object.table.split.unit.kb = 1;
SELECT get_data_from_oss('project.default.ot_demo_day', key) FROM ot_demo_da WHERE ...

若需要在某些情况下主动希望关闭此查询优化方案(该方案会启动两个作业,第一个作业负责进行一些预处理,并且可以在Logview上查看相关信息)。因此,MaxCompute的Object Table表也提供了相应的解决方案:

SET odps.sql.object.table.split.by.object.size.enabled = false;
SELECT get_data_from_oss('project.default.ot_demo_day', key) FROM ot_demo_day WHERE ...

删除OBJECT TABLE

Object Table本身会缓存用户的元信息,这将占用一定的存储空间并产生存储成本。因此,如果用户在业务上不再需要这些缓存数据,可以选择删除Object Table表。如后续业务需要重新使用这些数据,可以重建Object Table。

语法

DROP TABLE [IF EXISTS] <objecttable_name>; 

参数说明

objecttable_name:必填,表名。

示例

DROP TABLE IF EXISTS ot_demo_day;

常见问题

ODPS-0010000:System internal error

  • 现象

    报错信息如下:

    ODPS-0010000:System internal error - 
    ActionHandler job failed with failinfo	storage service worker error occured: 
    common/io/oss/oss_file_system_cppsdk.cpp(919): 
    OSSRequestException: Status: -50, RequestId: , 
    ErrorCode: ClientError:-50, Message: E_HTTP_ERROR_CONN_REFUSED
  • 问题原因

    创建Object Table时用了OSS的公网连接地址。

  • 解决方式

    创建Object Table时location参数中的oss_endpoint需要用内网地址,获取方式见参数说明

周期性刷新不成功

  • 现象

当创建Object Table时设置了周期性刷新的参数,到达刷新周期后,未进行刷新。

  • 解决方式

请检查创建Object Table配置的location参数值是否用的是OSS内网网络域名信息,更多创建Object Table详情见参数说明

周期性刷新任务报错

  • 报错信息

    FAILED: ODPS-0010000:System internal error - ActionHandler job failed with failinfo storage service worker error occured: common/io/oss/oss_file_system_cppsdk.cpp(877): OSSRequestException: Status: -50, RequestId: , ErrorCode: ClientError:-50, Message:

  • 解决方式

    该报错为内部错误,可以通过工单联系MaxCompute技术支持团队获取支持。