1. ANALYZE 是什么,适合用在什么场景
ANALYZE语句用于为已存在的表采集统计信息(Statistics)并写回 Catalog。目前 Flink 只支持ANALYZE TABLE,而且需要你手动触发,不会自动采集。 (Apache Nightlies)
常见用途(工程视角):
- 批处理场景里,为 join / filter / agg 等提供更可靠的行数与列分布信息(让执行计划更“像样”)
- 分区表按分区采集统计,避免全表扫描式的统计计算
- 数据变更后(重跑/回灌/重分区)重新采集,减少计划误判
注意:当前
ANALYZE TABLE只支持 Batch 模式;并且只支持已存在的物理表,如果是 view 或表不存在会抛异常。 (Apache Nightlies)
2. 如何执行 ANALYZE(Java / SQL CLI 都行)
在 Java 里,和 DDL/DML 一样,直接TableEnvironment.executeSql():
TableEnvironmenttableEnv=TableEnvironment.create(...);// 非分区表:只采集表级统计(row count)tableEnv.executeSql("ANALYZE TABLE Store COMPUTE STATISTICS");// 非分区表:采集表级 + 全列统计tableEnv.executeSql("ANALYZE TABLE Store COMPUTE STATISTICS FOR ALL COLUMNS");// 非分区表:只采集指定列统计tableEnv.executeSql("ANALYZE TABLE Store COMPUTE STATISTICS FOR COLUMNS location");分区表可以按分区范围采集(下面第 4 节详细讲)。 (Apache Nightlies)
3. 语法总览(背这一条就够了)
ANALYZETABLE[catalog_name.][db_name.]table_namePARTITION(partcol1[=val1][,partcol2[=val2],...])COMPUTESTATISTICS[FORCOLUMNScol1[,col2,...]|FORALLCOLUMNS]关键规则:
- 分区表必须带
PARTITION(...)(否则无法识别为分区采集逻辑)。 (Apache Nightlies) - 不写
FOR COLUMNS ... / FOR ALL COLUMNS时:只采集表级统计。 (Apache Nightlies) - 指定了列时:会采集列级统计;列必须存在且必须是物理列,否则抛异常。 (Apache Nightlies)
- 非分区表如果写了
PARTITION(...):会抛异常。 (Apache Nightlies) - 指定了分区但分区不存在:会抛异常。 (Apache Nightlies)
4. 分区表怎么采集:采一个分区 / 多个分区 / 全部分区
假设分区表Orders的分区列是(sold_year, sold_month, sold_day),并且存在这些分区: (Apache Nightlies)
- (2022, 1, 10)
- (2022, 1, 11)
- (2022, 2, 10)
- (2022, 2, 11)
4.1 只采集某一个具体分区
ANALYZETABLEOrdersPARTITION(sold_year='2022',sold_month='1',sold_day='10')COMPUTESTATISTICS;(Apache Nightlies)
4.2 采集“一个范围内的多个分区”(部分分区列给定值,剩余不写值)
下面这种写法表示:sold_year=2022 且 sold_month=1,sold_day不限定,因此会覆盖 (2022,1,10) 和 (2022,1,11):
ANALYZETABLEOrdersPARTITION(sold_year='2022',sold_month='1',sold_day)COMPUTESTATISTICS;(Apache Nightlies)
4.3 采集所有分区
ANALYZETABLEOrdersPARTITION(sold_year,sold_month,sold_day)COMPUTESTATISTICS;(Apache Nightlies)
4.4 分区表采集列级统计(全列 or 指定列)
-- 某分区:全列统计ANALYZETABLEOrdersPARTITION(sold_year='2022',sold_month='1',sold_day='10')COMPUTESTATISTICSFORALLCOLUMNS;-- 多分区范围:只采 amount、product 两列ANALYZETABLEOrdersPARTITION(sold_year='2022',sold_month='1',sold_day)COMPUTESTATISTICSFORCOLUMNSamount,product;(Apache Nightlies)
5. 到底采集了哪些列统计(Column Statistics)
当你指定FOR COLUMNS ...或FOR ALL COLUMNS时,会采集列级统计项(不同类型支持度不同): (Apache Nightlies)
- ndv:distinct 值数量(number of distinct values)
- nullCount:NULL 数量
- avgLen:平均长度(字符串类常见)
- maxLen:最大长度(字符串类常见)
- minValue / maxValue:最小/最大值(数值/时间类常见)
- valueCount:仅 boolean 类型的 value count
6. 类型支持矩阵(哪些类型能采哪些指标)
Flink 文档给出了“类型 vs 指标”的支持情况(Y 支持 / N 不支持)。这里按“你最常用的类型”总结: (Apache Nightlies)
- BOOLEAN:支持
nullCount、valueCount;不支持ndv/min/max/len - 数值类(TINYINT/SMALLINT/INT/BIGINT/FLOAT/DOUBLE/DECIMAL):支持
ndv/nullCount/min/max - 时间类(DATE/TIME/TIMESTAMP_LTZ/TIMESTAMP):支持
ndv/nullCount/min/max - 字符串类(CHAR/VARCHAR):支持
ndv/nullCount/avgLen/maxLen(不支持 min/max 值) - 其它复杂类型:多数只支持
nullCount,其它通常不支持
另外,定长类型(如 INTEGER/DOUBLE 等)不需要从原始记录采集 avgLen/maxLen。 (Apache Nightlies)
7. 一页结论
ANALYZE TABLE用于采集并存储统计信息到 Catalog,目前需要手动触发。 (Apache Nightlies)- 当前只支持Batch 模式;只支持已存在的物理表,view/不存在会报错。 (Apache Nightlies)
- 分区表必须写
PARTITION(...),可精确分区、范围分区或全部分区采集。 (Apache Nightlies) - 不指定列时只采表级统计;指定列后才会采列级统计(ndv/nullCount/len/min/max/valueCount 等)。 (Apache Nightlies)