为 CBO 收集统计信息
本主题介绍 StarRocks 基于成本的优化器 (CBO) 的基本概念,以及如何收集 CBO 的统计信息以选择最佳查询计划。 StarRocks 2.4 引入了直方图来收集准确的数据分布统计信息。
自 v3.2.0 起,StarRocks 支持从 Hive、Iceberg 和 Hudi 表收集统计信息,从而减少对其他元数据仓储系统的依赖。语法类似于收集 StarRocks 内部表。
什么是 CBO
CBO 对于查询优化至关重要。 SQL 查询到达 StarRocks 后,会被解析为逻辑执行计划。 CBO 将逻辑计划重写和转换为多个物理执行计划。然后,CBO 估计计划中每个运算符的执行成本(例如 CPU、内存、网络和 I/O),并选择成本最低的查询路径作为最终物理计划。
StarRocks CBO 于 StarRocks 1.16.0 中推出,并从 1.19 开始默认启用。 StarRocks CBO 基于 Cascades 框架开发,根据各种统计信息估算成本。它能够在成千上万个执行计划中选择成本最低的执行计划,从而显着提高复杂查询的效率和性能。
统计信息对于 CBO 非常重要。它们决定了成本估算是否准确和有用。以下部分详细介绍了统计信息的类型、收集策略以及如何收集统计信息和查看统计信息。
统计信息类型
StarRocks 收集各种统计信息作为成本估算的输入。
基本统计信息
默认情况下,StarRocks 定期收集表和列的以下基本统计信息
-
row_count:表中的总行数
-
data_size:列的数据大小
-
ndv:列基数,即列中不同值的数量
-
null_count:列中具有 NULL 值的数据量
-
min:列中的最小值
-
max:列中的最大值
完整统计信息存储在 _statistics_
数据库的 column_statistics
中。您可以查看此表以查询表统计信息。以下是从该表查询统计数据的一个示例。
SELECT * FROM _statistics_.column_statistics\G
*************************** 1. row ***************************
table_id: 10174
partition_id: 10170
column_name: is_minor
db_id: 10169
table_name: zj_test.source_wiki_edit
partition_name: p06
row_count: 2
data_size: 2
ndv: NULL
null_count: 0
max: 1
min: 0
直方图
StarRocks 2.4 引入了直方图来补充基本统计信息。直方图被认为是数据表示的一种有效方法。对于数据倾斜的表,直方图可以准确反映数据分布。
StarRocks 使用等高直方图,该直方图在多个桶上构建。每个桶包含相同数量的数据。对于经常查询且对选择性有重大影响的数据值,StarRocks 为它们分配单独的桶。更多的桶意味着更准确的估计,但也会导致内存使用量的轻微增加。您可以调整直方图收集任务的桶数和最常见值 (MCV) 的数量。
直方图适用于具有高度倾斜数据和频繁查询的列。如果您的表数据分布均匀,则无需创建直方图。直方图只能在数字、DATE、DATETIME 或字符串类型的列上创建。
直方图存储在 _statistics_
数据库的 histogram_statistics
表中。以下是从该表查询统计数据的一个示例
SELECT * FROM _statistics_.histogram_statistics\G
*************************** 1. row ***************************
table_id: 10174
column_name: added
db_id: 10169
table_name: zj_test.source_wiki_edit
buckets: NULL
mcv: [["23","1"],["5","1"]]
update_time: 2023-12-01 15:17:10.274000
多列联合统计
自 v3.5.0 起,StarRocks 支持多列联合统计信息收集。目前,当 StarRocks 执行基数估计时,大多数情况下优化器都假设多列之间完全相互独立,也就是说,它们之间没有关联。但是,如果列之间存在关联,则当前的估计方法可能会导致错误的结果。这会导致优化器生成不正确的执行计划。目前,仅支持多列联合 NDV,主要用于以下场景进行基数估计。
- 评估多个 AND 连接的等效谓词。
- 评估 Agg 节点。
- 应用于聚合下推策略。
目前,多列联合统计信息收集仅支持手动收集。默认类型是采样收集。多列统计信息存储在每个 StarRocks 集群的 _statistics_
数据库的 multi_column_statistics
表中。查询将返回类似于以下内容的信息
mysql> select * from _statistics_.multi_column_statistics \G
*************************** 1. row ***************************
table_id: 1695021
column_ids: 0#1
db_id: 110099
table_name: db.test_multi_col_stats
column_names: id,name
ndv: 11
update_time: 2025-04-11 15:09:50
收集类型和方法
表中的数据大小和数据分布不断变化。必须定期更新统计信息以表示数据更改。在创建统计信息收集任务之前,您必须选择最适合您业务需求的收集类型和方法。
StarRocks 支持全量和采样收集,两者都可以自动和手动执行。默认情况下,StarRocks 自动收集表的完整统计信息。它会每 5 分钟检查一次数据更新。如果检测到数据更改,将自动触发数据收集。如果您不想使用自动全量收集,您可以自定义收集任务。
收集类型 | 收集方法 | 描述 | 优点和缺点 |
---|---|---|---|
全量收集 | 自动/手动 | 扫描整个表以收集统计信息。统计信息是按分区收集的。如果分区没有数据更改,则不会从该分区收集数据,从而减少资源消耗。完整统计信息存储在 _statistics_.column_statistics 表中。 | 优点:统计信息准确,有助于 CBO 做出准确估计。缺点:消耗系统资源且速度慢。从 2.5 开始,StarRocks 允许您指定自动收集周期,从而减少资源消耗。 |
采样收集 | 自动/手动 | 从表的每个分区中均匀提取 N 行数据。统计信息是按表收集的。每列的基本统计信息存储为一条记录。列的基数信息 (ndv) 是基于采样数据估计的,不准确。采样统计信息存储在 _statistics_.table_statistic_v1 表中。 | 优点:消耗较少的系统资源且速度快。缺点:统计信息不完整,可能会影响成本估算的准确性。 |
自 v3.5.0 起,采样和全量收集统计信息都存储在 _statistics_.column_statistics
表中。这是因为当前的优化器将专注于基数估计中最近收集的统计信息,而每次后台自动收集统计信息时,由于表的不同运行状况,可能会使用不同的收集方法。如果存在数据倾斜,则全表的采样统计信息的错误率可能更高,并且由于收集方法的不同,同一查询可能会使用不同的统计信息,这可能会导致优化器生成不正确的执行计划。因此,采样收集和全量收集都假设统计信息是在分区级别收集的。您可以通过将 FE 配置项 statistic_use_meta_statistics
修改为 false
来调整到之前的收集和存储方法。
谓词列
自 v3.5.0 起,StarRocks 支持收集谓词列统计信息。
谓词列是在查询中经常用作过滤条件(WHERE 子句、JOIN 条件、GROUP BY 列、DISTINCT 列)的列。 StarRocks 会自动记录查询中涉及的表的每个谓词列,并将其存储在 _statistics_. predicate_columns
表中。查询将返回以下内容
select * from _statistics_.predicate_columns \G
*************************** 1. row ***************************
fe_id: 127.0.0.1_9011_1735874871718
db_id: 1684773
table_id: 1685786
column_id: 1
usage: normal,predicate,join,group_by
last_used: 2025-04-11 20:39:32
created: 2025-04-11 20:39:53
您还可以查询 information_schema.column_stats_usage
视图以获取更可观察的信息。在极端情况下(列数众多),全量收集开销很大,而实际上,对于稳定的工作负载,您通常不需要所有列的统计信息,而只需要某些关键 Filter、Join 和 Aggregation 中涉及的列的统计信息。因此,为了权衡成本和准确性,StarRocks 支持手动收集谓词列统计信息,并在自动收集统计信息时根据策略收集谓词列统计信息,从而避免收集表中所有列统计信息。集群中的每个 FE 节点都会定期将谓词列信息同步更新到 FE 缓存中,以加速使用。
收集统计信息
StarRocks 提供灵活的统计信息收集方法。您可以选择自动、手动或自定义收集,以适应您的业务场景。
默认情况下,StarRocks 会定期自动收集表的完整统计信息。默认间隔为 10 分钟。如果系统发现数据的更新率满足条件,则会自动触发收集。 收集完整统计信息可能会消耗大量系统资源。如果您不想使用自动完整统计信息收集,您可以将 FE 配置项 enable_collect_full_statistic
设置为 false
,并且定期收集任务将从完整统计信息收集更改为采样收集。
自 v3.5.0 起,StarRocks 将自动将全量收集更改为采样收集,如果它发现自从上次收集到当前表以来,表的数据已发生很大变化。在使用采样收集的情况下,如果表中存在谓词列 (PREDICATE/JOIN/GROUP BY/DISTINCT),StarRocks 会将采样任务转换为全量收集,并收集谓词列的统计信息以确保统计信息的准确性,并且不会收集表中所有列的统计信息。它不会收集表中所有列的统计信息。您可以使用 FE 配置项 statistic_auto_collect_use_full_predicate_column_for_sample
对此进行配置。此外,如果表中的列数超过 FE 配置项 statistic_auto_collect_predicate_columns_threshold
,StarRocks 还会从所有列的全量收集切换到谓词列的全量收集。
自动收集
对于基本统计信息,StarRocks 默认自动收集表的完整统计信息,无需手动操作。对于未收集统计信息的表,StarRocks 会在调度周期内自动收集统计信息。对于已收集统计信息的表,StarRocks 会更新表中的总行数和修改的行数,并定期保留此信息以判断是否触发自动收集。直方图和多列联合统计信息不会被当前的自动收集任务捕获。
从 2.4.5 开始,StarRocks 允许您指定自动全量收集的收集周期,这可以防止自动全量收集引起的集群性能抖动。此周期由 FE 参数 statistic_auto_analyze_start_time
和 statistic_auto_analyze_end_time
指定。
将触发自动收集的条件
-
自上次统计信息收集以来,表数据已更改。
-
收集时间落在配置的收集周期范围内。(默认收集周期是全天。)
-
先前收集作业的更新时间早于分区的最新更新时间。
-
表统计信息的运行状况低于指定的阈值 (
statistic_auto_collect_ratio
)。
计算统计信息运行状况的公式
- 如果数据更新的分区数少于 10,则公式为
1 - (自上次收集以来更新的行数/总行数)
。- 如果数据更新的分区数大于或等于 10,则公式为
1 - MIN(自上次收集以来更新的行数/总行数,自上次收集以来更新的分区数/总分区数)
。- 自 v3.5.0 起,为了确定分区是否健康,StarRocks 不再比较统计信息收集时间与数据更新时间,而是比较分区更新行的比率。您可以通过 FE 配置项
statistic_partition_health_v2_threshold
对此进行配置。此外,您可以将 FE 配置项statistic_partition_healthy_v2
设置为false
以使用先前的运行状况检查行为。
此外,StarRocks 允许您根据表大小和表更新频率配置收集策略
-
对于数据量小的表,**统计信息会实时收集,没有限制,即使表数据经常更新。
statistic_auto_collect_small_table_size
参数可用于确定表是小表还是大表。您还可以使用statistic_auto_collect_small_table_interval
配置小表的收集间隔。 -
对于数据量大的表,以下限制适用
-
默认收集间隔不小于 12 小时,可以使用
statistic_auto_collect_large_table_interval
进行配置。 -
当满足收集间隔且统计信息运行状况低于自动采样收集的阈值时,将触发采样收集。您可以使用 FE 配置项
statistic_auto_collect_sample_threshold
配置此行为。自 v3.5.0 起,如果满足以下所有条件,采样收集将转换为谓词列的全量收集- 谓词列存在于表中,并且谓词列的数量小于
statistic_auto_collect_max_predicate_column_size_on_sample_strategy
。 - FE 配置
statistic_auto_collect_use_full_predicate_column_for_sample
设置为true
。
- 谓词列存在于表中,并且谓词列的数量小于
-
当满足收集间隔且统计信息运行状况高于自动采样收集的阈值 (
statistic_auto_collect_sample_threshold
) 且低于自动收集阈值 (statistic_auto_collect_ratio
) 时,将触发全量收集。 -
当要收集数据的分区大小 (
statistic_max_full_collect_data_size
) 大于 100 GB 时,将触发采样收集。 -
仅收集更新时间晚于先前收集任务时间的分区的统计信息。不收集没有数据更改的分区的统计信息。
-
-
对于具有谓词列且总列数超过
statistic_auto_collect_predicate_columns_threshold
的表,仅收集表中谓词列的统计信息。
在更改表的数据后,为此表手动触发采样收集任务将使采样收集任务的更新时间晚于数据更新时间,这将不会在本调度周期内为此表触发自动全量收集。
默认情况下启用自动全量收集,并由系统使用默认设置运行。
下表描述了默认设置。如果您需要修改它们,请运行 ADMIN SET CONFIG 命令。
FE 配置项 | 类型 | 默认值 | 描述 |
---|---|---|---|
enable_statistic_collect | BOOLEAN | TRUE | 是否打开默认和用户定义的自动收集任务。默认情况下启用此开关。 |
enable_collect_full_statistic | BOOLEAN | TRUE | 是否启用默认自动收集。默认情况下启用此开关。 |
statistic_collect_interval_sec | LONG | 600 | 自动收集期间检查数据更新的间隔。单位:秒。 |
statistic_auto_analyze_start_time | STRING | 00:00:00 | 自动收集的开始时间。取值范围:00:00:00 - 23:59:59 。 |
statistic_auto_analyze_end_time | STRING | 23:59:59 | 自动收集的结束时间。取值范围:00:00:00 - 23:59:59 。 |
statistic_auto_collect_small_table_size | LONG | 5368709120 | 用于确定表是否为自动全量收集的小表的阈值。大小大于此值的表被认为是大型表,而大小小于或等于此值的表被认为是小型表。单位:字节。默认值:5368709120 (5 GB)。 |
statistic_auto_collect_small_table_interval | LONG | 0 | 自动收集小表的完整统计信息的间隔。单位:秒。 |
statistic_auto_collect_large_table_interval | LONG | 43200 | 自动收集大型表的完整统计信息的间隔。单位:秒。默认值:43200(12 小时)。 |
statistic_auto_collect_ratio | FLOAT | 0.8 | 用于确定自动收集的统计信息是否健康的阈值。如果统计信息运行状况低于此阈值,则会触发自动收集。 |
statistic_auto_collect_sample_threshold | DOUBLE | 0.3 | 用于触发自动采样收集的统计信息运行状况阈值。如果统计信息的运行状况值低于此阈值,则会触发自动采样收集。 |
statistic_max_full_collect_data_size | LONG | 107374182400 | 自动收集的分区要收集数据的数据大小。单位:字节。默认值:107374182400 (100 GB)。如果数据大小超过此值,则会放弃全量收集,而执行采样收集。 |
statistic_full_collect_buffer | LONG | 20971520 | 自动收集任务占用的最大缓冲区大小。单位:字节。默认值:20971520 (20 MB)。 |
statistic_collect_max_row_count_per_query | INT | 5000000000 | 单个分析任务要查询的最大行数。如果超过此值,分析任务将拆分为多个查询。 |
statistic_collect_too_many_version_sleep | LONG | 600000 | 如果运行收集任务的表具有过多的数据版本,则自动收集任务的休眠时间。单位:毫秒。默认值:600000(10 分钟)。 |
statistic_auto_collect_use_full_predicate_column_for_sample | BOOLEAN | TRUE | 当自动全量收集任务命中采样收集策略时,是否将自动全量收集任务转换为谓词列的全量收集。 |
statistic_auto_collect_max_predicate_column_size_on_sample_strategy | INT | 16 | 当自动全量收集任务命中采样收集策略时,如果表中的谓词列数量异常多并超过此配置项,则任务不会切换到谓词列的全量收集,而是保持为所有列的采样收集。此配置项控制此行为的谓词列的最大值。 |
statistic_auto_collect_predicate_columns_threshold | INT | 32 | 如果在自动收集期间表中的列数超过此配置,则仅收集谓词列的列统计信息。 |
statistic_predicate_columns_persist_interval_sec | LONG | 60 | FE 同步和持久化谓词列统计信息的间隔。 |
statistic_predicate_columns_ttl_hours | LONG | 24 | FE 中缓存的谓词列统计信息的消除时间。 |
您可以依靠自动作业来收集大部分统计信息,但如果您有特定要求,您可以手动执行 ANALYZE TABLE 语句来创建任务,或者通过执行 CREATE ANALYZE 语句来自定义自动任务。
手动收集
您可以使用 ANALYZE TABLE 创建手动收集任务。默认情况下,手动收集是同步操作。您也可以将其设置为异步操作。在异步模式下,运行 ANALYZE TABLE 后,系统会立即返回此语句是否成功。但是,收集任务将在后台运行,您无需等待结果。您可以通过运行 SHOW ANALYZE STATUS 检查任务的状态。异步收集适用于数据量大的表,而同步收集适用于数据量小的表。 手动收集任务在创建后仅运行一次。您无需删除手动收集任务。 您必须具有对相应表的 INSERT 和 SELECT 权限才能执行 ANALYZE TABLE 操作。
手动收集基本统计信息
ANALYZE [FULL|SAMPLE] TABLE tbl_name
[( col_name [, col_name]... )
| col_name [, col_name]...
| ALL COLUMNS
| PREDICATE COLUMNS
| MULTIPLE COLUMNS ( col_name [, col_name]... )]
[PARTITION (partition_name [, partition_name]...)]
[WITH [SYNC | ASYNC] MODE]
[PROPERTIES (property [, property]...)]
参数说明
-
收集类型
- FULL:表示全量收集。
- SAMPLE:表示采样收集。
- 如果未指定收集类型,则默认使用全量收集。
-
从中收集统计信息的列的类型
col_name
:从中收集统计信息的列。用逗号 (,
) 分隔多个列。如果未指定此参数,则收集整个表。ALL COLUMNS
:从所有列收集统计信息。自 v3.5.0 起支持。PREDICATE COLUMNS
:仅从谓词列收集统计信息。自 v3.5.0 起支持。MULTIPLE COLUMNS
:从指定的多列收集联合统计信息。目前,仅支持手动同步收集多列。手动统计信息收集的列数不能超过statistics_max_multi_column_combined_num
,默认值为10
。自 v3.5.0 起支持。
-
[WITH SYNC | ASYNC MODE]:手动收集任务是否以同步或异步模式运行。如果您未指定此参数,则默认使用同步收集。
-
PROPERTIES
:自定义参数。如果未指定PROPERTIES
,则使用fe.conf
文件中的默认设置。实际使用的属性可以通过 SHOW ANALYZE STATUS 的输出中的Properties
列查看。
PROPERTIES | 类型 | 默认值 | 描述 |
---|---|---|---|
statistic_sample_collect_rows | INT | 200000 | 采样收集要收集的最小行数。如果参数值超过表中实际的行数,则执行全量收集。 |
示例
手动全量收集
-- Manually collect full stats of a table using default settings.
ANALYZE TABLE tbl_name;
-- Manually collect full stats of a table using default settings.
ANALYZE FULL TABLE tbl_name;
-- Manually collect stats of specified columns in a table using default settings.
ANALYZE TABLE tbl_name(c1, c2, c3);
手动采样收集
-- Manually collect partial stats of a table using default settings.
ANALYZE SAMPLE TABLE tbl_name;
-- Manually collect stats of specified columns in a table, with the number of rows to collect specified.
ANALYZE SAMPLE TABLE tbl_name (v1, v2, v3) PROPERTIES(
"statistic_sample_collect_rows" = "1000000"
);
- 手动收集多列联合统计信息
-- Manual sampled collection of multi-column joint statistics
ANALYZE SAMPLE TABLE tbl_name MULTIPLE COLUMNS (v1, v2);
-- Manual full collection of multi-column joint statistics
ANALYZE FULL TABLE tbl_name MULTIPLE COLUMNS (v1, v2);
- 手动收集谓词列
-- Manual sampled collection of Predicate Column
ANALYZE SAMPLE TABLE tbl_name PREDICATE COLUMNS
-- Manual full collection of Predicate Column
ANALYZE FULL TABLE tbl_name PREDICATE COLUMNS
手动收集直方图
ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON col_name [, col_name]
[WITH SYNC | ASYNC MODE]
[WITH N BUCKETS]
[PROPERTIES (property [,property])]
参数说明
-
col_name
:从中收集统计信息的列。用逗号 (,
) 分隔多个列。如果未指定此参数,则收集整个表。此参数对于直方图是必需的。 -
[WITH SYNC | ASYNC MODE]:手动收集任务是否以同步或异步模式运行。如果您未指定此参数,则默认使用同步收集。
-
WITH N BUCKETS
:N
是直方图收集的桶数。如果未指定,则使用fe.conf
中的默认值。 -
PROPERTIES:自定义参数。如果未指定
PROPERTIES
,则使用fe.conf
中的默认设置。
PROPERTIES | 类型 | 默认值 | 描述 |
---|---|---|---|
statistic_sample_collect_rows | INT | 200000 | 要收集的最小行数。如果参数值超过表中实际的行数,则执行全量收集。 |
histogram_buckets_size | LONG | 64 | 直方图的默认桶数。 |
histogram_mcv_size | INT | 100 | 直方图的最常见值 (MCV) 的数量。 |
histogram_sample_ratio | FLOAT | 0.1 | 直方图的采样率。 |
histogram_max_sample_row_count | LONG | 10000000 | 直方图要收集的最大行数。 |
直方图要收集的行数由多个参数控制。它是 statistic_sample_collect_rows
和表行数 * histogram_sample_ratio
之间的较大值。该数字不能超过 histogram_max_sample_row_count
指定的值。如果超过该值,则 histogram_max_sample_row_count
优先。
实际使用的属性可以通过 SHOW ANALYZE STATUS 的输出中的 Properties
列查看。
示例
-- Manually collect histograms on v1 using the default settings.
ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON v1;
-- Manually collect histograms on v1 and v2, with 32 buckets, 32 MCVs, and 50% sampling ratio.
ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON v1,v2 WITH 32 BUCKETS
PROPERTIES(
"histogram_mcv_size" = "32",
"histogram_sample_ratio" = "0.5"
);
自定义收集
自定义自动收集任务
StarRocks 提供的默认收集任务根据策略自动收集所有数据库和所有表的统计信息,默认情况下,您不需要创建自定义收集任务。
如果您想自定义自动收集任务,您需要通过 CREATE ANALYZE 语句创建它。要创建收集任务,您需要对要收集的表具有 INSERT 和 SELECT 权限。
-- Automatically collect stats of all databases.
CREATE ANALYZE [FULL|SAMPLE] ALL [PROPERTIES (property [,property])]
-- Automatically collect stats of all tables in a database.
CREATE ANALYZE [FULL|SAMPLE] DATABASE db_name
[PROPERTIES (property [,property])]
-- Automatically collect stats of specified columns in a table.
CREATE ANALYZE [FULL|SAMPLE] TABLE tbl_name (col_name [,col_name])
[PROPERTIES (property [,property])]
-- Automatically collect histograms of specified columns in a table.
CREATE ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON col_name [, col_name]
[WITH SYNC | ASYNC MODE]
[WITH N BUCKETS]
[PROPERTIES (property [,property])]
参数说明
-
收集类型
- FULL:表示全量收集。
- SAMPLE:表示采样收集。
- 如果未指定收集类型,则默认使用采样收集。
-
col_name
:从中收集统计信息的列。用逗号 (,
) 分隔多个列。如果未指定此参数,则收集整个表。 -
PROPERTIES
:自定义参数。如果未指定PROPERTIES
,则使用fe.conf
文件中的默认设置。
PROPERTIES | 类型 | 默认值 | 描述 |
---|---|---|---|
statistic_auto_collect_ratio | FLOAT | 0.8 | 用于确定自动收集的统计信息是否健康的阈值。如果统计信息运行状况低于此阈值,则会触发自动收集。 |
statistic_sample_collect_rows | INT | 200000 | 要收集的最小行数。如果参数值超过表中的实际行数,则执行完整收集。 |
statistic_exclude_pattern | 字符串 | null | 需要在作业中排除的数据库或表的名称。您可以指定作业中不收集统计信息的数据库和表。请注意,这是一个正则表达式模式,匹配内容为 database.table 。 |
statistic_auto_collect_interval | LONG | 0 | 自动收集的间隔。单位:秒。默认情况下,StarRocks 会根据表的大小选择 statistic_auto_collect_small_table_interval 或 statistic_auto_collect_large_table_interval 作为收集间隔。如果您在创建分析作业时指定了 statistic_auto_collect_interval 属性,则此设置优先于 statistic_auto_collect_small_table_interval 和 statistic_auto_collect_large_table_interval 。 |
示例
自动完整收集
-- Automatically collect full stats of all databases.
CREATE ANALYZE ALL;
-- Automatically collect full stats of a database.
CREATE ANALYZE DATABASE db_name;
-- Automatically collect full stats of all tables in a database.
CREATE ANALYZE FULL DATABASE db_name;
-- Automatically collect full stats of specified columns in a table.
CREATE ANALYZE TABLE tbl_name(c1, c2, c3);
-- Automatically collect stats of all databases, excluding specified database 'db_name'.
CREATE ANALYZE ALL PROPERTIES (
"statistic_exclude_pattern" = "db_name\."
);
-- Automatically collect histograms of specified database, table, or columns.
CREATE ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON c1,c2;
自动抽样收集
-- Automatically collect stats of all tables in a database with default settings.
CREATE ANALYZE SAMPLE DATABASE db_name;
-- Automatically collect stats of all tables in a database, excluding specified table 'db_name.tbl_name'.
CREATE ANALYZE SAMPLE DATABASE db_name PROPERTIES (
"statistic_exclude_pattern" = "db_name.tbl_name"
);
-- Automatically collect stats of specified columns in a table, with statistics health and the number of rows to collect specified.
CREATE ANALYZE SAMPLE TABLE tbl_name(c1, c2, c3) PROPERTIES (
"statistic_auto_collect_ratio" = "0.5",
"statistic_sample_collect_rows" = "1000000"
);
不使用 StarRocks 提供的自动收集任务,而是使用用户定义的收集任务,该任务不收集 db_name.tbl_name
表。
ADMIN SET FRONTEND CONFIG("enable_auto_collect_statistics"="false");
DROP ALL ANALYZE JOB;
CREATE ANALYZE FULL ALL db_name PROPERTIES (
"statistic_exclude_pattern" = "db_name.tbl_name"
);
数据加载期间收集统计信息
为了确保在数据加载后立即获得良好的查询执行计划,StarRocks 在 INSERT INTO/OVERWRITE DML 语句结束后触发一个异步统计信息收集任务,默认情况下,该任务在 DML 结束后等待 30 秒。如果统计信息收集任务在 30 秒内未完成,则返回 DML 执行结果。
INSERT INTO
- 仅针对首次将数据导入到分区时收集统计信息。
- 如果本次导入的行数大于
statistic_sample_collect_rows
,则触发抽样收集任务,否则使用完整收集。
INSERT OVERWRITE
- 如果在 OVERWRITE 操作前后行数变化的比例小于
statistic_sample_collect_ratio_threshold_of_first_load
,则不触发统计信息收集任务。 - 如果此 OVERWRITE 操作中的行数大于
statistic_sample_collect_rows
,则触发抽样收集任务,否则使用完整收集。
以下属性 (PROPERTIES) 用于为数据加载创建自定义收集任务。如果未配置,则使用相应的 FE 配置项的值。
PROPERTIES | 类型 | 默认值 | 描述 |
---|---|---|---|
enable_statistic_collect_on_first_load | BOOLEAN | TRUE | 是否在执行 INSERT INTO/OVERWRITE 后触发统计信息收集任务。 |
semi_sync_collect_statistic_await_seconds | LONG | 30 | 在返回结果之前等待收集统计信息的最长时间。 |
statistic_sample_collect_ratio_threshold_of_first_load | DOUBLE | 0.1 | 不触发统计信息收集任务的 OVERWRITE 操作中的数据更改比率。 |
statistic_sample_collect_rows | LONG | 200000 | 当通过 DML 语句加载的总数据行数超过此值时,将使用抽样收集进行统计信息收集。 |
查看自定义收集任务
SHOW ANALYZE JOB [WHERE predicate][ORDER BY columns][LIMIT num]
您可以使用 WHERE 子句过滤结果。该语句返回以下列。
列 | 描述 |
---|---|
Id | 收集任务的 ID。 |
数据库 | 数据库名称。 |
Table | 表名。 |
Columns | 列名。 |
类型 | 统计信息的类型,包括 FULL 和 SAMPLE 。 |
Schedule | 调度的类型。对于自动任务,类型为 SCHEDULE 。 |
Properties | 自定义参数。 |
Status | 任务状态,包括 PENDING、RUNNING、SUCCESS 和 FAILED。 |
LastWorkTime | 上次收集的时间。 |
Reason | 任务失败的原因。如果任务执行成功,则返回 NULL。 |
示例
-- View all the custom collection tasks.
SHOW ANALYZE JOB
-- View custom collection tasks of database `test`.
SHOW ANALYZE JOB where `database` = 'test';
删除自定义收集任务
DROP ANALYZE <ID>
| DROP ALL ANALYZE JOB
可以通过使用 SHOW ANALYZE JOB 语句获取任务 ID。
示例
DROP ANALYZE 266030;
DROP ALL ANALYZE JOB;
查看收集任务的状态
您可以通过运行 SHOW ANALYZE STATUS 语句来查看所有当前任务的状态。此语句不能用于查看自定义收集任务的状态。要查看自定义收集任务的状态,请使用 SHOW ANALYZE JOB。
SHOW ANALYZE STATUS [WHERE predicate];
您可以使用 LIKE 或 WHERE
来过滤要返回的信息。
此语句返回以下列。
List name | 描述 |
---|---|
Id | 收集任务的 ID。 |
数据库 | 数据库名称。 |
Table | 表名。 |
Columns | 列名。 |
类型 | 统计信息的类型,包括 FULL、SAMPLE 和 HISTOGRAM。 |
Schedule | 调度的类型。 ONCE 表示手动,SCHEDULE 表示自动。 |
Status | 任务的状态。 |
StartTime | 任务开始执行的时间。 |
EndTime | 任务执行结束的时间。 |
Properties | 自定义参数。 |
Reason | 任务失败的原因。如果执行成功,则返回 NULL。 |
查看统计信息
查看基本统计信息的元数据
SHOW STATS META [WHERE predicate][ORDER BY columns][LIMIT num]
此语句返回以下列。
列 | 描述 |
---|---|
数据库 | 数据库名称。 |
Table | 表名。 |
Columns | 列名。 |
类型 | 统计信息的类型。 FULL 表示完整收集,SAMPLE 表示抽样收集。 |
UpdateTime | 当前表的最新统计信息更新时间。 |
Properties | 自定义参数。 |
Healthy | 统计信息的健康状况。 |
ColumnStats | Column ANALYZE 类型。 |
TabletStatsReportTime | 表 Tablet 元数据在 FE 中更新的时间。 |
TableHealthyMetrics | 统计信息中的健康指标。 |
TableUpdateTime | 表更新的时间。 |
查看直方图的元数据
SHOW HISTOGRAM META [WHERE predicate]
此语句返回以下列。
列 | 描述 |
---|---|
数据库 | 数据库名称。 |
Table | 表名。 |
列 | 列。 |
类型 | 统计信息的类型。对于直方图,值为 HISTOGRAM 。 |
UpdateTime | 当前表的最新统计信息更新时间。 |
Properties | 自定义参数。 |
删除统计信息
您可以删除不需要的统计信息。当您删除统计信息时,统计信息的数据和元数据以及过期缓存中的统计信息都会被删除。请注意,如果自动收集任务正在进行中,则可能会再次收集以前删除的统计信息。您可以使用 SHOW ANALYZE STATUS
查看收集任务的历史记录。
删除基本统计信息
以下语句删除存储在 default_catalog._statistics_.column_statistics
表中的统计信息,并且 FE 缓存的相应表统计信息也将失效。从 v3.5.0 开始,此语句还会删除此表的多列联合统计信息。
DROP STATS tbl_name
以下语句删除存储在 default_catalog._statistics_.multi_column_statistics
表中的多列联合统计信息,并且 FE 缓存的相应表中的多列联合统计信息也将失效。此语句不会删除表的基本统计信息。
DROP MULTIPLE COLUMNS STATS tbl_name
删除直方图
ANALYZE TABLE tbl_name DROP HISTOGRAM ON col_name [, col_name]
取消收集任务
您可以使用 KILL ANALYZE 语句取消**正在运行**的收集任务,包括手动任务和自定义任务。
KILL ANALYZE <ID>
手动收集任务的任务 ID 可以从 SHOW ANALYZE STATUS 中获取。自定义收集任务的任务 ID 可以从 SHOW ANALYZE SHOW ANALYZE JOB 中获取。
其他 FE 配置项
FE 配置项 | 类型 | 默认值 | 描述 |
---|---|---|---|
statistic_manager_sleep_time_sec | LONG | 60 | 调度元数据的间隔。单位:秒。系统根据此间隔执行以下操作:创建用于存储统计信息的表。删除已删除的统计信息。删除过期的统计信息。 |
statistic_analyze_status_keep_second | LONG | 259200 | 保留收集任务历史记录的持续时间。单位:秒。默认值:259200(3 天)。 |
会话变量
statistic_collect_parallel
:用于调整可以在 BE 上运行的统计信息收集任务的并行性。默认值:1。您可以增加此值以加快收集任务。
收集外部表的统计信息
自 v3.2.0 起,StarRocks 支持收集 Hive、Iceberg 和 Hudi 表的统计信息。语法类似于收集 StarRocks 内部表。**但是,仅支持手动完整收集、手动直方图收集(自 v3.2.7 起)和自动完整收集。不支持抽样收集。** 自 v3.3.0 起,StarRocks 支持收集 Delta Lake 表的统计信息以及 STRUCT 中子字段的统计信息。自 v3.4.0 起,StarRocks 支持通过查询触发的 ANALYZE 任务自动收集统计信息。
收集的统计信息存储在 default_catalog
中 _statistics_
的 external_column_statistics
表中。它们不存储在 Hive Metastore 中,也不能被其他搜索引擎共享。您可以从 default_catalog._statistics_.external_column_statistics
表中查询数据以验证是否为 Hive/Iceberg/Hudi 表收集了统计信息。
以下是从 external_column_statistics
查询统计信息数据的示例。
SELECT * FROM _statistics_.external_column_statistics\G
*************************** 1. row ***************************
table_uuid: hive_catalog.tn_test.ex_hive_tbl.1673596430
partition_name:
column_name: k1
catalog_name: hive_catalog
db_name: tn_test
table_name: ex_hive_tbl
row_count: 3
data_size: 12
ndv: NULL
null_count: 0
max: 3
min: 2
update_time: 2023-12-01 14:57:27.137000
限制
以下限制适用于您收集外部表的统计信息时
- 您只能收集 Hive、Iceberg、Hudi 和 Delta Lake(自 v3.3.0 起)表的统计信息。
- 仅支持手动完整收集、手动直方图收集(自 v3.2.7 起)和自动完整收集。不支持抽样收集。
- 为了使系统自动收集完整统计信息,您必须创建一个 Analyze 作业,这与收集 StarRocks 内部表的统计信息不同,在 StarRocks 内部表中,系统默认在后台执行此操作。
- 对于自动收集任务
- 您只能收集特定表的统计信息。您不能收集数据库中所有表的统计信息或外部 Catalog 中所有数据库的统计信息。
- StarRocks 可以检测 Hive 和 Iceberg 表中的数据是否已更新,如果是,则仅收集数据已更新的分区的统计信息。StarRocks 无法感知 Hudi 表中的数据是否已更新,只能执行定期完整收集。
- 对于查询触发的收集任务
- 当前,只有 Leader FE 节点可以触发 ANALYZE 任务。
- 系统仅支持检查 Hive 和 Iceberg 表上的分区更改,并且仅收集数据已更改的分区的统计信息。对于 Delta Lake/Hudi 表,系统会收集整个表的统计信息。
- 如果 Partition Transforms 应用于 Iceberg 表,则仅支持
identity
、year
、month
、day
、hour
类型 Transforms 的统计信息收集。 - 不支持为 Iceberg 表收集 Partition Evolution 的统计信息。
以下示例发生在 Hive 外部 Catalog 下的数据库中。如果您想从 default_catalog
收集 Hive 表的统计信息,请以 [catalog_name.][database_name.]<table_name>
格式引用该表。
查询触发的收集
自 v3.4.0 起,系统支持通过查询触发的 ANALYZE 任务自动收集外部表的统计信息。在查询 Hive、Iceberg、Hudi 或 Delta Lake 表时,系统会自动在后台触发 ANALYZE 任务,以收集相应表和列的统计信息,并将其用于后续查询计划优化。
工作流程
- 当优化器查询 FE 中的缓存统计信息时,它将根据查询的表和列确定 ANALYZE 任务的对象(ANALYZE 任务只会收集查询中包含的列的统计信息)。
- 系统会将任务对象封装为 ANALYZE 任务,并将其添加到 PendingTaskQueue。
- Scheduler 线程定期从 PendingTaskQueue 中获取任务,并将其添加到 RunningTasksQueue。
- 在 ANALYZE 任务的执行过程中,它会收集统计信息并将其写入 BE,并清除 FE 中缓存的过期统计信息。
默认情况下启用此功能。您可以使用以下系统变量和配置项来控制上述过程。
系统变量
enable_query_trigger_analyze
- 默认值:true
- 类型:Boolean
- 描述:是否启用查询触发 ANALYZE 任务。
- 引入于:v3.4.0
FE 配置
connector_table_query_trigger_analyze_small_table_rows
- 默认值:10000000
- 类型:Int
- 单位:-
- 是否可变:是
- 描述:用于确定表是否为查询触发 ANALYZE 任务的小表的阈值。
- 引入于:v3.4.0
connector_table_query_trigger_analyze_small_table_interval
- 默认值:2 * 3600
- 类型:Int
- 单位:秒
- 是否可变:是
- 描述:小表的查询触发 ANALYZE 任务的间隔。
- 引入于:v3.4.0
connector_table_query_trigger_analyze_large_table_interval
- 默认值:12 * 3600
- 类型:Int
- 单位:秒
- 是否可变:是
- 描述:大表的查询触发 ANALYZE 任务的间隔。
- 引入于:v3.4.0
connector_table_query_trigger_analyze_max_pending_task_num
- 默认值:100
- 类型:Int
- 单位:-
- 是否可变:是
- 描述:FE 上处于 Pending 状态的查询触发 ANALYZE 任务的最大数量。
- 引入于:v3.4.0
connector_table_query_trigger_analyze_schedule_interval
- 默认值:30
- 类型:Int
- 单位:秒
- 是否可变:是
- 描述:Scheduler 线程调度查询触发 ANALYZE 任务的间隔。
- 引入于:v3.4.0
connector_table_query_trigger_analyze_max_running_task_num
- 默认值:2
- 类型:Int
- 单位:-
- 是否可变:是
- 描述:FE 上处于 Running 状态的查询触发 ANALYZE 任务的最大数量。
- 引入于:v3.4.0
手动收集
您可以按需创建一个 Analyze 作业,该作业在您创建后立即运行。
创建手动收集任务
语法
-- Manual full collection
ANALYZE [FULL] TABLE tbl_name (col_name [,col_name])
[WITH SYNC | ASYNC MODE]
[PROPERTIES(property [,property])]
-- Manual histogram collection (since v3.3.0)
ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON col_name [, col_name]
[WITH SYNC | ASYNC MODE]
[WITH N BUCKETS]
[PROPERTIES (property [,property])]
以下是手动完整收集的示例
ANALYZE TABLE ex_hive_tbl(k1);
+----------------------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------------------------------+---------+----------+----------+
| hive_catalog.tn_test.ex_hive_tbl | analyze | status | OK |
+----------------------------------+---------+----------+----------+
查看任务状态
语法
SHOW ANALYZE STATUS [LIKE | WHERE predicate]
示例
SHOW ANALYZE STATUS where `table` = 'ex_hive_tbl';
+-------+----------------------+-------------+---------+------+----------+---------+---------------------+---------------------+------------+--------+
| Id | Database | Table | Columns | Type | Schedule | Status | StartTime | EndTime | Properties | Reason |
+-------+----------------------+-------------+---------+------+----------+---------+---------------------+---------------------+------------+--------+
| 16400 | hive_catalog.tn_test | ex_hive_tbl | k1 | FULL | ONCE | SUCCESS | 2023-12-04 16:31:42 | 2023-12-04 16:31:42 | {} | |
| 16465 | hive_catalog.tn_test | ex_hive_tbl | k1 | FULL | ONCE | SUCCESS | 2023-12-04 16:37:35 | 2023-12-04 16:37:35 | {} | |
| 16467 | hive_catalog.tn_test | ex_hive_tbl | k1 | FULL | ONCE | SUCCESS | 2023-12-04 16:37:46 | 2023-12-04 16:37:46 | {} | |
+-------+----------------------+-------------+---------+------+----------+---------+---------------------+---------------------+------------+--------+
查看统计信息的元数据
语法
SHOW STATS META [WHERE predicate]
示例
SHOW STATS META where `table` = 'ex_hive_tbl';
+----------------------+-------------+---------+------+---------------------+------------+---------+
| Database | Table | Columns | Type | UpdateTime | Properties | Healthy |
+----------------------+-------------+---------+------+---------------------+------------+---------+
| hive_catalog.tn_test | ex_hive_tbl | k1 | FULL | 2023-12-04 16:37:46 | {} | |
+----------------------+-------------+---------+------+---------------------+------------+---------+
取消收集任务
取消正在运行的收集任务。
语法
KILL ANALYZE <ID>
您可以在 SHOW ANALYZE STATUS 的输出中查看任务 ID。
自动收集
为了使系统自动收集外部数据源中表的统计信息,您可以创建一个 Analyze 作业。StarRocks 会在默认检查间隔 5 分钟自动检查是否运行该任务。对于 Hive 和 Iceberg 表,仅当表中的数据更新时,StarRocks 才会运行收集任务。
但是,Hudi 表中的数据更改无法感知,StarRocks 会根据您指定的检查间隔和收集间隔定期收集统计信息。您可以指定以下 FE 配置项来控制收集行为
-
statistic_collect_interval_sec
自动收集期间检查数据更新的间隔。单位:秒。默认值:5 分钟。
-
statistic_auto_collect_small_table_rows(v3.2 及更高版本)
用于确定外部数据源(Hive、Iceberg、Hudi)中的表在自动收集期间是否为小表的阈值。默认值:10000000。
-
statistic_auto_collect_small_table_interval
收集小表统计信息的间隔。单位:秒。默认值:0。
-
statistic_auto_collect_large_table_interval
收集大表统计信息的间隔。单位:秒。默认值:43200(12 小时)。
自动收集线程以 statistic_collect_interval_sec
指定的间隔检查数据更新。如果表中的行数小于 statistic_auto_collect_small_table_rows
,它将根据 statistic_auto_collect_small_table_interval
收集此类表的统计信息。
如果表中的行数超过 statistic_auto_collect_small_table_rows
,它将根据 statistic_auto_collect_large_table_interval
收集此类表的统计信息。仅当 上次表更新时间 + 收集间隔 > 当前时间
时,它才会更新大表的统计信息。这可以防止对大表执行频繁的分析任务。
创建自动收集任务
语法
CREATE ANALYZE TABLE tbl_name (col_name [,col_name])
[PROPERTIES (property [,property])]
您可以指定属性 statistic_auto_collect_interval
来专门为自动收集任务设置收集间隔。FE 配置项 statistic_auto_collect_small_table_interval
和 statistic_auto_collect_large_table_interval
将不会对此任务生效。
示例
CREATE ANALYZE TABLE ex_hive_tbl (k1)
PROPERTIES ("statistic_auto_collect_interval" = "5");
Query OK, 0 rows affected (0.01 sec)
查看自动收集任务的状态
与手动收集相同。
查看统计信息的元数据
与手动收集相同。
查看自动收集任务
语法
SHOW ANALYZE JOB [WHERE predicate]
示例
SHOW ANALYZE JOB WHERE `id` = '17204';
Empty set (0.00 sec)
取消收集任务
与手动收集相同。
删除统计信息
DROP STATS tbl_name
参考
-
要查询 FE 配置项,请运行 ADMIN SHOW CONFIG。
-
要修改 FE 配置项,请运行 ADMIN SET CONFIG。