暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Startrocks之CBO 统计信息

原创 飞鸟-柯 2023-03-01
1020

本文介绍 StarRocks CBO(Cost-based Optimizer)优化器的基本概念,以及如何为 CBO 优化器采集统计信息。StarRocks 2.4 版本引入直方图作为统计信息,提供准确的数据分布统计。

什么是 CBO 优化器

CBO 优化器是查询优化的关键。一条 SQL 查询到达 StarRocks 后,会解析为一条逻辑执行计划,CBO 优化器对逻辑计划进行改写和转换,生成多个物理执行计划。通过估算计划中每个算子的执行代价(CPU、内存、网络、I/O 等资源消耗),选择代价最低的一条查询路径作为最终的物理查询计划。

StarRocks CBO 优化器采用 Cascades 框架,基于多种统计信息进行代价估算,能够在数万级别的执行计划中,选择代价最低的执行计划,提升复杂查询的效率和性能。StarRocks 1.16.0 版本推出自研的 CBO 优化器。1.19 版本及以上,该特性默认开启。

统计信息是 CBO 优化器的重要组成部分,统计信息的准确与否决定了代价估算是否准确,进而决定了CBO 优化器的性能好坏。下文详细介绍统计信息的类型、采集策略、以及如何创建采集任务和查看统计信息。

统计信息类型

StarRocks 会采集多种统计信息,为查询优化提供代价估算的参考。

基础统计信息

StarRocks 默认定期采集表和列的如下基础信息:

  • row_count : 表的总行数

  • data_size: 列的数据大小

  • ndv: 列基数,即 distinct value 的个数

  • null_count: 列中 NULL 值的个数

  • min: 列的最小值

  • max: 列的最大值

基础统计信息存储在 _statistics_.table_statistic_v1 表中,您可以在 StarRocks 集群 _statistics_ 数据库下查看。

直方图

从 2.4 版本开始,StarRocks 引入直方图 (Histogram)。直方图常用于估算数据分布,当数据存在倾斜时,直方图可以弥补基础统计信息估算存在的偏差,输出更准确的数据分布信息。

StarRocks 采用等深直方图 (Equi-height Histogram),即选定若干个 bucket,每个 bucket 中的数据量几乎相等。对于出现频次较高、对选择率(selectivity)影响较大的数值,StarRocks 会分配单独的桶进行存储。桶数量越多时,直方图的估算精度就越高,但是也会增加统计信息的内存使用。您可以根据业务情况调整直方图的桶个数和单个采集任务的 MCV(most common value) 个数。

直方图适用于有明显数据倾斜,并且有频繁查询请求的列。如果您的表数据分布比较均匀,可以不使用直方图。直方图支持的列类型为数值类型、DATE、DATETIME 或字符串类型。

目前直方图仅支持手动抽样采集。直方图统计信息存储在 _statistics_ 数据库的 histogram_statistics 表中。

采集类型

表的大小和数据分布会频繁更新,需要定期更新统计信息,确保统计信息能准确反映表中的实际数据。在创建采集任务之前,您需要根据业务场景决定使用哪种采集类型和采集方式。

StarRocks 支持全量采集 (full collection) 和抽样采集 (sampled collection)。全量采集和抽样采集均支持自动和手动采集方式。

默认情况下,StarRocks 会周期性自动采集表的全量统计信息。默认检查更新时间为 5 分钟一次,如果发现有数据更新,会自动触发采集。如果您不希望使用自动全量采集,可以设置 FE 配置项 enable_collect_full_statistic 为 false,系统会停止自动全量采集,根据您创建的自定义任务进行定制化采集。

采集类型采集方式采集方法优缺点
全量采集自动或手动扫描全表,采集真实的统计信息值。按照分区(Partition)级别采集,基础统计信息的相应列会按照每个分区采集一条统计信息。如果对应分区无数据更新,则下次自动采集时,不再采集该分区的统计信息,减少资源占用。全量统计信息存储在 _statistics_.column_statistics 表中。优点:统计信息准确,有利于CBO更准确地估算执行计划。缺点:消耗大量系统资源,速度较慢。从 2.5 版本开始支持用户配置自动采集的时间段,减少资源消耗。
抽样采集自动或手动从表的每个分区中均匀抽取 N 行数据,计算统计信息。抽样统计信息按照表级别采集,基础统计信息的每一列会存储一条统计信息。列的基数信息 (ndv) 是按照抽样样本估算的全局基数,和真实的基数信息会存在一定偏差。抽样统计信息存储在 _statistics_.table_statistic_v1 表中。优点:消耗较少的系统资源,速度快。 缺点:统计信息存在一定误差,可能会影响 CBO 评估执行计划的准确性。

采集统计信息

StarRocks 提供灵活的信息采集方式,您可以根据业务场景选择自动采集、手动采集,也可以自定义自动采集任务。

自动全量采集 (Auto Full Collection)

对于基础统计信息,StarRocks 默认自动进行全表全量统计信息采集,无需人工操作。对于从未采集过统计信息的表,会在一个调度周期内自动进行统计信息采集。对于已经采集过统计信息的表,StarRocks 会自动更新表的总行数以及修改的行数,将这些信息定期持久化下来,作为是否触发自动采集的判断条件。

从 2.5 版本开始,支持用户配置自动全量采集的时间段,防止因集中采集而导致的集群性能抖动。采集时间段可通过 statistic_auto_analyze_start_time 和 statistic_auto_analyze_end_time 这两个 FE 配置项来配置。

触发自动采集的判断条件:

  • 上次统计信息采集之后,该表是否发生过数据变更。

  • 该表的统计信息健康度(statistic_auto_collect_ratio)是否低于配置阈值。

健康度计算公式: 1 - 上次统计信息采集后的新增行数/最小分区的总行数

  • 该分区数据是否发生过修改,未发生过修改的分区不做重新采集。

  • 采集是否落在配置的自动采集时间段内(默认为全天采集,可进行修改)。

自动全量采集任务由系统自动执行,默认配置如下。您可以通过 ADMIN SET CONFIG 命令修改。

FE配置项类型默认值说明
enable_statistic_collectBOOLEANTRUE是否采集统计信息。该参数默认打开。
enable_collect_full_statisticBOOLEANTRUE是否开启自动全量统计信息采集。该参数默认打开。
statistic_collect_interval_secLONG300自动定期任务中,检测数据更新的间隔,默认 5 分钟。单位:秒。
statistic_auto_collect_ratioFLOAT0.8自动统计信息的健康度阈值。如果统计信息的健康度小于该阈值,则触发自动采集。
statistic_max_full_collect_data_sizeLONG107374182400自动统计信息采集的最大分区的大小。单位:Byte。如果某个分区超过该值,则放弃全量统计信息采集,转为对该表进行抽样采集。
statistic_collect_max_row_count_per_queryLONG5000000000统计信息采集单次最多查询的数据行数。统计信息任务会按照该配置自动拆分为多次任务执行。
statistic_auto_analyze_start_timeSTRING00:00:00用于配置自动全量采集的起始时间。取值范围:00:00:00 ~ 23:59:59
statistic_auto_analyze_end_timeSTRING23:59:59用于配置自动全量采集的结束时间。取值范围:00:00:00 ~ 23:59:59

手动采集 (Manual Collection)

可以通过 ANALYZE TABLE 语句创建手动采集任务。手动采集默认为同步操作。您也可以将手动任务设置为异步,执行命令后,系统会立即返回命令的状态,但是统计信息采集任务会异步在后台运行。异步采集适用于表数据量大的场景,同步采集适用于表数据量小的场景。 手动任务创建后仅会执行一次,无需手动删除。运行状态可以使用 SHOW ANALYZE STATUS 查看。

手动采集基础统计信息

ANALYZE [FULL|SAMPLE] TABLE tbl_name (col_name [,col_name]) [WITH SYNC | ASYNC MODE] PROPERTIES (property [,property]);

参数说明:

  • 采集类型

    • FULL:全量采集。
    • SAMPLE:抽样采集。
    • 如果不指定采集类型,默认为全量采集。
  • WITH SYNC | ASYNC MODE: 如果不指定,默认为同步采集。

  • col_name: 要采集统计信息的列,多列使用逗号分隔。如果不指定,表示采集整张表的信息。

  • PROPERTIES: 采集任务的自定义参数。如果不配置,则采用fe.conf中的默认配置。

PROPERTIES类型默认值说明
statistic_sample_collect_rowsINT200000最小采样行数。如果参数取值超过了实际的表行数,默认进行全量采集。

示例

手动全量采集 (Manual full collection)

-- 手动全量采集指定表的统计信息,使用默认配置。 ANALYZE TABLE tbl_name; -- 手动全量采集指定表的统计信息,使用默认配置。 ANALYZE FULL TABLE tbl_name; -- 手动全量采集指定表指定列的统计信息,使用默认配置。 ANALYZE TABLE tbl_name(c1, c2, c3);

手动抽样采集 (Manual sampled collection)

-- 手动抽样采集指定表的统计信息,使用默认配置。 ANALYZE SAMPLE TABLE tbl_name; -- 手动抽样采集指定表指定列的统计信息,设置抽样行数。 ANALYZE SAMPLE TABLE tbl_name (v1, v2, v3) PROPERTIES( "statistic_sample_collect_rows" = "1000000" );

手动采集直方图统计信息

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 BUCKETSN 为直方图的分桶数。如果不指定,则使用 fe.conf 中的默认值。

  • PROPERTIES: 采集任务的自定义参数。如果不指定,则使用 fe.conf 中的默认配置。

PROPERTIES类型默认值说明
statistic_sample_collect_rowsINT200000最小采样行数。如果参数取值超过了实际的表行数,默认进行全量采集。
histogram_mcv_sizeINT100直方图 most common value (MCV) 的数量。
histogram_sample_ratioFLOAT0.1直方图采样比例。
histogram_max_sample_row_countLONG10000000直方图最大采样行数。

直方图的采样行数由多个参数共同控制,采样行数取 statistic_sample_collect_rows 和表总行数 histogram_sample_ratio 两者中的最大值。最多不超过 histogram_max_sample_row_count 指定的行数。如果超过,则按照该参数定义的上限行数进行采集。

直方图任务实际执行中使用的 PROPERTIES,可以通过 SHOW ANALYZE STATUS 中的 PROPERTIES 列查看。

示例

-- 手动采集v1列的直方图信息,使用默认配置。 ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON v1; -- 手动采集v1列的直方图信息,指定32个分桶,mcv指定为32个,采样比例为50%。 ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON v1,v2 WITH 32 BUCKETS PROPERTIES( "histogram_mcv_size" = "32", "histogram_sample_ratio" = "0.5" );

自定义自动采集 (Custom Collection)

创建自动采集任务

可以通过 CREATE ANALYZE 语句创建自定义自动采集任务。

创建自定义自动采集任务之前,需要先关闭自动全量采集 enable_collect_full_statistic=false,否则自定义采集任务不生效。

-- 定期采集所有数据库的统计信息。 CREATE ANALYZE [FULL|SAMPLE] ALL PROPERTIES (property [,property]); -- 定期采集指定数据库下所有表的统计信息。 CREATE ANALYZE [FULL|SAMPLE] DATABASE db_name PROPERTIES (property [,property]); -- 定期采集指定表、列的统计信息。 CREATE ANALYZE [FULL|SAMPLE] TABLE tbl_name (col_name [,col_name]) PROPERTIES (property [,property]);

参数说明:

  • 采集类型

    • FULL:全量采集。
    • SAMPLE:抽样采集。
    • 如果不指定采集类型,默认为全量采集。
  • col_name: 要采集统计信息的列,多列使用逗号 (,)分隔。如果不指定,表示采集整张表的信息。

  • PROPERTIES: 采集任务的自定义参数。如果不配置,则采用fe.conf中的默认配置。

PROPERTIES类型默认值说明
statistic_auto_collect_ratioFLOAT0.8自动统计信息的健康度阈值。如果统计信息的健康度小于该阈值,则触发自动采集。
statistics_max_full_collect_data_sizeINT100自动统计信息采集的最大分区的大小。单位: GB。如果某个分区超过该值,则放弃全量统计信息采集,转为对该表进行抽样统计信息采集。
statistic_sample_collect_rowsINT200000抽样采集的采样行数。如果该参数取值超过了实际的表行数,则进行全量采集。

示例

自动全量采集

-- 定期全量采集所有数据库的统计信息。 CREATE ANALYZE ALL; -- 定期全量采集指定数据库下所有表的统计信息。 CREATE ANALYZE DATABASE db_name; -- 定期全量采集指定数据库下所有表的统计信息。 CREATE ANALYZE FULL DATABASE db_name; -- 定期全量采集指定表、列的统计信息。 CREATE ANALYZE TABLE tbl_name(c1, c2, c3);

自动抽样采集

-- 定期抽样采集指定数据库下所有表的统计信息。 CREATE ANALYZE SAMPLE DATABASE db_name; -- 定期抽样采集指定表、列的统计信息,设置采样行数和健康度阈值。 CREATE ANALYZE SAMPLE TABLE tbl_name(c1, c2, c3) PROPERTIES( "statistic_auto_collect_ratio" = "0.5", "statistic_sample_collect_rows" = "1000000" );

查看自动采集任务

SHOW ANALYZE JOB [WHERE predicate]

您可以使用 WHERE 子句设定筛选条件,进行返回结果筛选。该语句会返回如下列。

列名说明
Id采集任务的ID。
Database数据库名。
Table表名。
Columns列名列表。
Type统计信息的类型。取值: FULL,SAMPLE。
Schedule调度的类型。自动采集任务固定为 SCHEDULE
Properties自定义参数信息。
Status任务状态,包括 PENDING(等待)、RUNNING(正在执行)、SUCCESS(执行成功)和 FAILED(执行失败)。
LastWorkTime最近一次采集时间。
Reason任务失败的原因。如果执行成功则为 NULL

示例

-- 查看集群全部自定义采集任务。 SHOW ANALYZE JOB -- 查看数据库test下的自定义采集任务。 SHOW ANALYZE JOB where `database` = 'test';

删除自动采集任务

DROP ANALYZE <ID>;

示例

DROP ANALYZE 266030;

查看采集任务状态

您可以通过 SHOW ANALYZE STATUS 语句查看当前所有采集任务的状态。该语句不支持查看自定义采集任务的状态,如要查看,请使用 SHOW ANALYZE JOB

SHOW ANALYZE STATUS [LIKE | WHERE predicate];

您可以使用 Like 或 Where 来筛选需要返回的信息。

目前 SHOW ANALYZE STATUS 会返回如下列。

列名说明
Id采集任务的ID。
Database数据库名。
Table表名。
Columns列名列表。
Type统计信息的类型,包括 FULL,SAMPLE,HISTOGRAM。
Schedule调度的类型。ONCE 表示手动,SCHEDULE 表示自动。
Status任务状态,包括 RUNNING(正在执行)、SUCCESS(执行成功)和 FAILED(执行失败)。
StartTime任务开始执行的时间。
EndTime任务结束执行的时间。
Properties自定义参数信息。
Reason任务失败的原因。如果执行成功则为 NULL。

查看统计信息

基础统计信息元数据

SHOW STATS META [WHERE predicate];

该语句返回如下列。

列名说明
Database数据库名。
Table表名。
Columns列名。
Type统计信息的类型,FULL 表示全量,SAMPLE 表示抽样。
UpdateTime当前表的最新统计信息更新时间。
Properties自定义参数信息。
Healthy统计信息健康度。

直方图统计信息元数据

SHOW HISTOGRAM META [WHERE predicate];

该语句返回如下列。

列名说明
Database数据库名。
Table表名。
Column列名。
Type统计信息的类型,直方图固定为 HISTOGRAM
UpdateTime当前表的最新统计信息更新时间。
Properties自定义参数信息。

删除统计信息

StarRocks 支持手动删除统计信息。手动删除统计信息时,会删除统计信息数据和统计信息元数据,并且会删除过期内存中的统计信息缓存。需要注意的是,如果当前存在自动采集任务,可能会重新采集之前已删除的统计信息。您可以使用 SHOW ANALYZE STATUS 查看统计信息采集历史记录。

删除基础统计信息

DROP STATS tbl_name

删除直方图统计信息

ANALYZE TABLE tbl_name DROP HISTOGRAM ON col_name [, col_name];

取消采集任务

您可以通过 KILL ANALYZE 语句取消正在运行中(Running)的统计信息采集任务,包括手动采集任务和自定义自动采集任务。

手动采集任务的任务 ID 可以在 SHOW ANALYZE STATUS 中查看。自定义自动采集任务的任务 ID 可以在 SHOW ANALYZE JOB 中查看。

KILL ANALYZE <ID>;

FE配置项说明

FE配置项类型默认值说明
enable_statistic_collectBOOLEANTRUE是否采集统计信息。该参数默认打开。
enable_collect_full_statisticBOOLEANTRUE是否开启自动全量统计信息采集。该参数默认打开。
statistic_auto_collect_ratioFLOAT0.8自动统计信息的健康度阈值。如果统计信息的健康度小于该阈值,则触发自动采集。
statistic_max_full_collect_data_sizeLONG107374182400自动统计信息采集的最大分区的大小。单位:Byte。如果某个分区超过该值,则放弃全量统计信息采集,转为对该表进行抽样采集。
statistic_collect_max_row_count_per_queryLONG5000000000统计信息采集单次最多查询的数据行数。统计信息任务会按照该配置自动拆分为多次任务执行。
statistic_collect_interval_secLONG300自动定期任务中,检测数据更新的间隔时间,默认为 5 分钟。单位:秒。
statistic_auto_analyze_start_timeSTRING00:00:00用于配置自动全量采集的起始时间。取值范围:00:00:00 ~ 23:59:59
statistic_auto_analyze_end_timeSTRING23:59:59用于配置自动全量采集的结束时间。取值范围:00:00:00 ~ 23:59:59
statistic_sample_collect_rowsLONG200000最小采样行数。如果指定了采集类型为抽样采集(SAMPLE),需要设置该参数。
如果参数取值超过了实际的表行数,默认进行全量采集。
statistic_collect_concurrencyINT3手动采集任务的最大并发数,默认为 3,即最多可以有 3 个手动采集任务同时运行。
超出的任务处于 PENDING 状态,等待调度。
histogram_buckets_sizeLONG64直方图默认分桶数。
histogram_mcv_sizeLONG100直方图默认 most common value 的数量。
histogram_sample_ratioFLOAT0.1直方图默认采样比例。
histogram_max_sample_row_countLONG10000000直方图最大采样行数。
statistic_manager_sleep_time_secLONG60统计信息相关元数据调度间隔周期。单位:秒。系统根据这个间隔周期,来执行如下操作:
  • 创建统计信息表;
  • 删除已经被删除的表的统计信息;
  • 删除过期的统计信息历史记录。
statistic_analyze_status_keep_secondLONG259200采集任务记录保留时间,默认为 3 天。单位:秒。

更多信息

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论