ANALYZE 语句

ANALYZE 语句 #

ANALYZE 语句被用于为存在的表收集统计信息,并将统计信息写入该表的 catalog 中。当前版本中,ANALYZE 语句只支持 ANALYZE TABLE, 且只能由用户手动触发。

注意 现在, ANALYZE TABLE 只支持批模式(Batch Mode),且只能用于已存在的表, 如果表不存在或者是视图(View)则会报错。

执行 ANALYZE TABLE 语句 #

可以使用 TableEnvironmentexecuteSql() 方法执行 ANALYZE TABLE 语句。

以下示例展示了如何在 TableEnvironment 中执行一条 ANALYZE TABLE 语句。

可以使用 TableEnvironmentexecuteSql() 方法执行 ANALYZE TABLE 语句。

以下示例展示了如何在 TableEnvironment 中执行一条 ANALYZE TABLE 语句。

可以使用 TableEnvironmentexecute_sql() 方法执行 ANALYZE TABLE 语句。

以下示例展示了如何在 TableEnvironment 中执行一条 ANALYZE TABLE 语句。

ANALYZE TABLE 语句可以在 SQL CLI 中执行。

以下示例展示了如何在 SQL CLI 中执行一条 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");
val 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");
table_env = TableEnvironment.create(...)

# 注册名为 “Store” 的非分区表
table_env.execute_sql(
  "CREATE TABLE Store (" +
          " `id` BIGINT NOT NULl," +
          " `location` VARCHAR(32)," +
          " `owner` VARCHAR(32)" +
          ") with (...)");

# 注册名为 “Orders” 的分区表
table_env.execute_sql(
  "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))。
table_env.execute_sql("ANALYZE TABLE Store COMPUTE STATISTICS");

# 非分区表,收集表级别的统计信息和所有列的列统计信息。
table_env.execute_sql("ANALYZE TABLE Store COMPUTE STATISTICS FOR ALL COLUMNS");

# 非分区表,收集表级别的统计信息和指定列(列: location)的列统计信息。
table_env.execute_sql("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 的表级别统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS");

# 分区表,收集分区 Partition1 和 Partition2 的表级别统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS");

# 分区表,为所有分区收集表级别统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS");

# 分区表,收集分区 Partition1 的表级别统计信息和所有列的统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS FOR ALL COLUMNS");

# 分区表,收集分区 Partition1 和 Partition2 的表级别统计信息和所有列统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS FOR ALL COLUMNS");

# 分区表,为所有分区收集表级别统计信息和所有列的统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS FOR ALL COLUMNS");

# 分区表,收集分区 Partition1 的表级别统计信息和分区中指定列(列: amount)的列统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS FOR COLUMNS amount");

# 分区表,收集分区 Partition1 和 Partition2 的表级别统计信息和分区中指定列(列: amount,列: product)的列统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS FOR COLUMNS amount, product");

# 分区表,收集所有分区的表级别统计信息和指定列(列: amount,列: product)的列统计信息。
table_env.execute_sql("ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS FOR COLUMNS amount, product");
Flink SQL> CREATE TABLE Store (
> `id` BIGINT NOT NULl,
> `location` VARCHAR(32),
> `owner` VARCHAR(32)
> ) with (
> ...
> );
[INFO] Table has been created.

Flink SQL> 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 (
> ...
> );
[INFO] Table has been created.

Flink SQL> ANALYZE TABLE Store COMPUTE STATISTICS;
[INFO] Execute statement succeed.
    
Flink SQL> ANALYZE TABLE Store COMPUTE STATISTICS FOR ALL COLUMNS;
[INFO] Execute statement succeed.

Flink SQL> ANALYZE TABLE Store COMPUTE STATISTICS FOR COLUMNS location;
[INFO] Execute statement succeed.
    
Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS;
[INFO] Execute statement succeed.

Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS;
[INFO] Execute statement succeed.

Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS;
[INFO] Execute statement succeed.

Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS FOR ALL COLUMNS;
[INFO] Execute statement succeed.

Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS FOR ALL COLUMNS;
[INFO] Execute statement succeed.
    
Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS FOR ALL COLUMNS;
[INFO] Execute statement succeed.
    
Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year='2022', sold_month='1', sold_day='10') COMPUTE STATISTICS FOR COLUMNS amount;
[INFO] Execute statement succeed.
    
Flink SQL> ANALYZE TABLE Orders PARTITION (sold_year='2022', sold_month='1', sold_day) COMPUTE STATISTICS FOR COLUMNS amount, product;
[INFO] Execute statement succeed.
    
Flink SQL> ANALYZE TABLE Orders PARTITION(sold_year, sold_month, sold_day) COMPUTE STATISTICS FOR COLUMNS amount, product;
[INFO] Execute statement succeed.

语法 #

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 不会去收集 avgLenmaxLen 值。

Back to top