ANALYZE 语句
ANALYZE 语句
ANALYZE
语句被用于为存在的表收集统计信息,并将统计信息写入该表的 catalog 中。当前版本中,ANALYZE
语句只支持 ANALYZE TABLE
,
且只能由用户手动触发。
注意
现在, ANALYZE TABLE
只支持批模式(Batch Mode),且只能用于已存在的表,
如果表不存在或者是视图(View)则会报错。
执行 ANALYZE TABLE 语句
可以使用 TableEnvironment
的 executeSql()
方法执行 ANALYZE TABLE
语句。
以下示例展示了如何在 TableEnvironment
中执行一条 ANALYZE TABLE
语句。
TableEnvironment tableEnv = TableEnvironment.create(...);
// 注册名为 “Store” 的非分区表
tableEnv.executeSql(
"CREATE TABLE Store (" +
" `id` BIGINT NOT NULl," +
" `location` VARCHAR(32)," +
" `owner` VARCHAR(32)" +
") with (...)");
// 注册名为 “Orders” 的分区表
tableEnv.executeSql(
"CREATE TABLE Orders (" +
" `id` BIGINT NOT NULl," +
" `product` VARCHAR(32)," +
" `amount` INT," +
" `sold_year` BIGINT", +
" `sold_month` BIGINT", +
" `sold_day` BIGINT" +
") PARTITIONED BY (`sold_year`, `sold_month`, `sold_day`) "
") with (...)");
// 非分区表,收集表级别的统计信息(表的统计信息主要为行数(row count))。
tableEnv.executeSql("ANALYZE TABLE Store COMPUTE STATISTICS");
// 非分区表,收集表级别的统计信息和所有列的列统计信息。
tableEnv.executeSql("ANALYZE TABLE Store COMPUTE STATISTICS FOR ALL COLUMNS");
// 非分区表,收集表级别的统计信息和指定列(列: location)的列统计信息。
tableEnv.executeSql("ANALYZE TABLE Store COMPUTE STATISTICS FOR COLUMNS location");
// 假设分区表 “Orders” 有 4 个分区,分区信息如下:
// Partition1 : (sold_year='2022', sold_month='1', sold_day='10')
// Partition2 : (sold_year='2022', sold_month='1', sold_day='11')
// Partition3 : (sold_year='2022', sold_month='2', sold_day='10')
// Partition4 : (sold_year='2022', sold_month='2', sold_day='11')
// 分区表,收集分区 Partition1 的表级别统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS");
// 分区表,收集分区 Partition1 和 Partition2 的表级别统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS");
// 分区表,为所有分区收集表级别统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS");
// 分区表,收集分区 Partition1 的表级别统计信息和所有列的统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS FOR ALL COLUMNS");
// 分区表,收集分区 Partition1 和 Partition2 的表级别统计信息和所有列统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS FOR ALL COLUMNS");
// 分区表,为所有分区收集表级别统计信息和所有列的统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS FOR ALL COLUMNS");
// 分区表,收集分区 Partition1 的表级别统计信息和分区中指定列(列: amount)的列统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS FOR COLUMNS amount");
// 分区表,收集分区 Partition1 和 Partition2 的表级别统计信息和分区中指定列(列: amount,列: product)的列统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS FOR COLUMNS amount, product");
// 分区表,收集所有分区的表级别统计信息和指定列(列: amount,列: product)的列统计信息。
tableEnv.executeSql("ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS FOR COLUMNS amount, product");
语法
ANALYZE TABLE [catalog_name.][db_name.]table_name PARTITION(partcol1[=val1] [, partcol2[=val2], ...]) COMPUTE STATISTICS [FOR COLUMNS col1 [, col2, ...] | FOR ALL COLUMNS]
对于分区表, 语法中 PARTITION(partcol1[=val1], partcol2[=val2], ...]) 是必须指定的
- 如果没有指定某分区,则会收集所有分区的统计信息
- 如果指定了某分区,则只会收集该分区的统计信息
- 如果该表为非分区表,但语句中指定了分区,则会报异常
- 如果指定了某个分区,但是该分区不存在,则会报异常
语法中,FOR COLUMNS col1 [, col2, ...] 或者 FOR ALL COLUMNS 也是可选的
- 如果没有指定某一列,则只会收集表级别的统计信息
- 如果指定的列不存在,或者该列不是物理列,则会报异常
- 如果指定了某一列或者某几列,则会收集列的统计信息
- 列级别的统计信息包括:
- ndv: 该列中列值不同的数量
- nullCount: 该列中空值的数量
- avgLen: 列值的平均长度
- maxLen: 列值的最大长度
- minValue: 列值的最小值
- maxValue: 列值的最大值
- valueCount: 该值只应用于 boolean 类型
- 对于列统计信息,支持类型和对应的列统计信息值如下表所示("Y" 代表支持,"N" 代表不支持):
类型 | ndv | nullCount | avgLen | maxLen | maxValue | minValue | valueCount |
---|---|---|---|---|---|---|---|
BOOLEAN | N | Y | N | N | N | N | Y |
TINYINT | Y | Y | N | N | Y | Y | N |
SMALLINT | Y | Y | N | N | Y | Y | N |
INTEGER | Y | Y | N | N | Y | Y | N |
FLOAT | Y | Y | N | N | Y | Y | N |
DATE | Y | Y | N | N | Y | Y | N |
TIME_WITHOUT_TIME_ZONE | Y | Y | N | N | Y | Y | N |
BIGINT | Y | Y | N | N | Y | Y | N |
DOUBLE | Y | Y | N | N | Y | Y | N |
DECIMAL | Y | Y | N | N | Y | Y | N |
TIMESTAMP_WITH_LOCAL_TIME_ZONE | Y | Y | N | N | Y | Y | N |
TIMESTAMP_WITHOUT_TIME_ZONE | Y | Y | N | N | Y | Y | N |
CHAR | Y | Y | Y | Y | N | N | N |
VARCHAR | Y | Y | Y | Y | N | N | N |
other types | N | Y | N | N | N | N | N |
注意: 对于数据值定长的类型(例如:BOOLEAN
, INTEGER
, DOUBLE
等), Flink 不会去收集 avgLen
和 maxLen
值。