news 2026/9/24 19:18:58

Presto ANALYZE 语句详解:表与列统计信息收集指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Presto ANALYZE 语句详解:表与列统计信息收集指南

Presto ANALYZE 语句详解:表与列统计信息收集指南

【免费下载链接】prestoThe official home of the Presto distributed SQL query engine for big data项目地址: https://gitcode.com/gh_mirrors/pre/presto

ANALYZE是 Presto 中用于收集表和列统计信息的 SQL 语句,这些统计信息(行数、空值数、去重值数、min/max 等)是查询优化器进行 Join 顺序选择、谓词下推等代价估算的关键输入。本文以 ANALYZE 官方文档 为核心,结合 Hive、Iceberg 连接器的实现源码与文档,完整讲解语法、WITH 属性、支持范围、实战示例及底层原理,帮助读者在 Presto 集群中正确、高效地维护统计信息。

语法(Synopsis)

ANALYZE table_name [ WITH ( property_name = expression [, ...] ) ]
  • table_name:目标表名,支持catalog.schema.table三段式全限定名,也可使用当前 catalog/schema 下的简化名称。
  • WITH子句:可选,用于传入连接器特定的属性(property),例如 Hive 连接器的partitions属性。

功能描述(Description)

ANALYZE用于收集指定表的表级与列级统计信息。需要注意当前实现的限制:

  • 目前仅为基本类型(primitive types)收集列统计信息,复杂类型(如ROWARRAYMAP等)不会生成列级统计。
  • 统计信息的具体种类由底层连接器决定。以 Hive 连接器为例,Hive 连接器文档 中列出的各类型统计项如下:
列类型收集的统计信息
TINYINT/SMALLINT/INTEGER/BIGINT/DOUBLE/REAL/DECIMAL/DATE/TIMESTAMPnull 数量、distinct 数量、min/max 值
VARCHAR/CHARnull 数量、distinct 数量
VARBINARYnull 数量
BOOLEANnull 数量、true/false 值数量

列出可用的 WITH 属性

WITH子句可用的属性是连接器相关的。要查看当前 Presto 版本下所有连接器注册的 analyze 属性,可直接查询系统表:

SELECT * FROM system.metadata.analyze_properties

该表由 AnalyzePropertiesSystemTable.java 实现,它继承自AbstractPropertiesSystemTable,数据来源是Metadata.getAnalyzePropertyManager().getAllProperties()——也就是把各连接器在启动时注册的 analyze 属性统一汇总后暴露给查询。因此,运行这条查询即可获得与当前部署连接器精确匹配的属性清单、类型与默认值。

支持的连接器

ANALYZE并非所有连接器都支持。根据官方文档,当前仅以下两个连接器支持:

  • Hive 连接器:见 Collecting table and column statistics,支持对分区表按分区收集统计信息。
  • Iceberg 连接器:见 Collecting table and column statistics,支持全表统计信息收集。

对其他连接器执行ANALYZE会得到不支持的错误。

实战示例(Examples)

1. 分析整张表

对当前 catalog/schema 下的表web收集统计信息:

ANALYZE web;

2. 使用三段式表名

指定 catalog 与 schema,避免歧义:

ANALYZE hive.default.stores;

Iceberg 表用法相同:

ANALYZE iceberg.default.stores;

Iceberg 连接器文档中的示例为ANALYZE iceberg.tpch.orders;,即对tpchschema 下的orders表收集统计信息。

3. 指定 Hive 分区表的部分分区

对于 Hive 分区表,默认会分析全部分区;也可以使用WITH (partitions = ...)精确定位需要分析的分区。partitions属性是一个外层数组,其中每个内层数组代表一个分区的各分区键值,键值的顺序必须与表 schema 中分区键的声明顺序一致

按单分区键(ds为分区键)分析两个日期分区:

ANALYZE hive.default.sales WITH (partitions = ARRAY[ARRAY['1992-01-01'], ARRAY['1992-01-02']]);

按复合分区键(分区键为statecity两列)分析两组分区:

ANALYZE hive.default.customers WITH (partitions = ARRAY[ARRAY['CA', 'San Francisco'], ARRAY['NY', 'NY']]);

Hive 连接器文档 给出的通用形式为:

ANALYZE hive.sales WITH ( partitions = ARRAY[ ARRAY['partition1_value1', 'partition1_value2'], ARRAY['partition2_value1', 'partition2_value2']]);

以上语句会分别收集分区键为partition1_value1, partition1_value2partition2_value1, partition2_value2的两个分区的统计信息。

4. Iceberg 表的全表分析

Iceberg 连接器目前只支持全表统计收集(且ANALYZE仅支持在 autocommit 模式下执行,参见 Iceberg 连接器文档 中的事务限制说明):

ANALYZE iceberg.default.stores;

源码级原理:Hive 连接器的 partitions 属性

partitions属性由 HiveAnalyzeProperties.java 定义与解析,可以从中看到几个值得注意的实现细节:

  • 属性名常量:public static final String PARTITIONS_PROPERTY = "partitions";
  • 属性类型声明为array(array(varchar)),即内层数组的每个元素都是字符串类型,这解释了为何日期分区值需要写成'1992-01-01'这样的字符串字面量。
  • getPartitionList(...)方法负责从解析后的属性 Map 中取出分区列表,未指定时返回Optional.empty()(表示分析全表/全部分区)。
  • decodePartitionLists(...)会把分区值中的null替换为 Hive 默认分区值(HIVE_DEFAULT_DYNAMIC_PARTITION),保证动态分区场景下也能正确匹配;同时会将结果转换为 Set 去重。
  • 若属性中出现null分区值,会抛出INVALID_ANALYZE_PROPERTY错误,提示 "Invalid null value in analyze partitions property"。

统计收集的执行入口

在 HiveMetadata.java 中,getStatisticsCollectionMetadata方法定义了ANALYZE执行时收集哪些统计:

  • 列统计范围:排除分区列(partitionedBy)与隐藏列(hidden)后的所有列;临时表使用getColumnStatisticMetadataForTemporaryTable,普通表使用getColumnStatisticMetadata(后者会通过 metastore 的getSupportedColumnStatistics确认该类型支持哪些统计项)。
  • 表统计:ANALYZE场景(includeRowCount = true)会额外收集行数(ROW_COUNT)。
  • 结果封装为TableStatisticsMetadata(columnStatistics, tableStatistics, partitionedBy),由引擎统一调度执行统计收集任务,最终写回连接器的 metastore。

Quick Stats 与 ANALYZE 的互补关系

对于尚未执行过ANALYZE的分区,Hive 连接器可以通过读取文件/表元数据(例如 Parquet footer)推断出行数、null 数和 min/max 等"快速统计"(Quick Stats),在查询规划阶段作为临时统计来源。其行为由以下属性控制(详见 Hive 连接器文档):

属性名说明默认值
hive.quick-stats.enabled是否启用 quick stats 收集;也可通过会话属性quick_stats_enabled动态开关false
hive.quick-stats.max-concurrent-callsquick stats 会并发构建,此参数控制最大并发调用数见连接器配置

使用建议与注意事项

  1. 分析时机:在批量写入、数据导入或 ETL 完成后执行ANALYZE,确保优化器基于最新统计信息生成执行计划;对于不断变化的分区,可针对性地分析近期写入的分区,而不是反复全表分析。
  2. 分区表的成本控制:Hive 大分区表上执行不带partitionsANALYZE会扫描全部分区,耗时与资源开销较大,应优先使用WITH (partitions = ...)精准定位。
  3. 连接器支持范围:目前只有 Hive 与 Iceberg 连接器支持ANALYZE;在部署多连接器集群时,先通过SELECT * FROM system.metadata.analyze_properties确认目标连接器注册了哪些属性。
  4. 统计信息驱动优化:准确的统计信息直接影响 Join 顺序选择、聚合与扫描阶段的代价估算。若查询计划出现明显退化,可先检查相关表是否缺少统计信息(例如 Hive 表存在缺失统计信息的分区时,可结合 Quick Stats 属性临时补充)。
  5. 类型限制:列统计仅覆盖基本类型,复杂类型列不会产生列级统计,规划阶段对这类列的估算依赖表级信息或连接器默认值。

通过以上语法、示例与源码解析,读者可以在 Presto 中熟练运用ANALYZE维护表与列统计信息,为查询优化器提供准确的代价估算依据,从而提升大规模数据查询的执行效率。

【免费下载链接】prestoThe official home of the Presto distributed SQL query engine for big data项目地址: https://gitcode.com/gh_mirrors/pre/presto

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 19:18:29

RabbitMQ集群部署实战:从Docker Compose到高可用与权限管理

开局先给结论:RabbitMQ集群部署这件事,本身不复杂,复杂的是部署完之后那一堆“看起来不报错、实际上用不了”的隐性问题。我见过太多人用Docker把RabbitMQ节点拉起来,进了管理界面兴奋不已,结果用admin账号去创建虚拟主…

作者头像 李华
网站建设 2026/9/24 19:16:29

openworkbuddy办公Agent深度解析:JavaScript+Markdown+MCP三体协同

1. 这不是选工具,是给办公流“装神经系统”:为什么我花三天时间把6个Agent项目拉进同一张表横向比烂你有没有过这种体验:早上打开电脑,邮箱里堆着23封待处理的客户询价,钉钉弹出5条跨部门协作需求,飞书文档…

作者头像 李华
网站建设 2026/9/24 19:15:51

Win7系统盘C盘爆满?老玩家分享瘦身清理全攻略

Windows 7这系统,说老是真老,但要说没人用,那也是骗人的。我自己手头就有几台老机器——工控机、旧笔记本、还有一台只认Win7驱动的老打印机工作站——到现在都还在跑Win7。这两年尤其有意思,网上又开始流行找“集成2019年补丁的W…

作者头像 李华
网站建设 2026/9/24 19:14:05

PSO-CNN回归预测实战:粒子群算法自动优化卷积神经网络超参数

简介:面向多变量输入的回归预测任务,这套Matlab完整源码实现了粒子群算法(PSO)优化卷积神经网络(CNN)的核心流程,主要自动搜索学习率、批大小、正则化系数等关键超参数,适用于风电、…

作者头像 李华
网站建设 2026/9/24 19:13:47

配电网动态最优潮流与网络重构:二阶锥松弛模型解析与实战

做配电网优化方向的人,大概率都绕不开这个组合:IEEE 33节点、动态最优潮流、网络重构、二阶锥松弛模型。我见过太多人,静态潮流程序跑得顺手,一到这个组合题就卡住——论文里式子一行接一行,但真要写成代码&#xff0c…

作者头像 李华
网站建设 2026/9/24 19:13:03

网络编程入门:从Socket API到手写TCP回显服务器

1. 网络编程入门,到底在学什么 先说个扎心的事实:很多人在大学里学了《计算机网络》,背了一堆 OSI 七层模型、TCP 三次握手四次挥手的八股文,但真要让他写一个能跑起来的服务端程序,立刻傻眼。教材教的是"网络怎么…

作者头像 李华