当前 ByteHouse 自研的查询优化器使用统计信息来提高查询性能。当前支持您手动创建 create stats 来收集数据表的统计信息或修改查询设计,从而提高查询性能。
以下内容将介绍如何创建统计信息,展示统计信息,删除统计信息。ByteHouse 也支持通过控制面开启统计信息,操作详情请参见设置统计信息功能。
CREATE STATS [IF NOT EXISTS] (<db>.* | *.* | [<db>.]<table>['(' <col1>, <col2>, ..., <coln> ')']) [WITH ...]
参数 | 是否必填 | 配置说明 |
|---|---|---|
CREATE STATS | 是 | 用于手动创建数据表统计信息的 SQL 命令。 |
| 否 | 可选参数。如果指定此参数,当统计信息已经存在时,不会抛出错误,而是忽略创建操作。 |
| 三选一 | 指定数据库中的所有表。格式为: |
| 三选一 | 指定当前环境中的所有数据库和表。与 |
| 三选一 | 指定特定的表。可选项包含数据库名,格式为: |
| 否 | 指定表中的特定列。格式为: |
WITH | 否 | 用于指定统计信息收集策略,支持指定自动或手动选择策略。
|
使用示例如下:
-- 为 t1 创建统计信息 create stats db1.t1; create stats t1; -- create stats for t1.c1, -- 为 t1 中 c1 列创建统计信息 create stats t1(c1); -- 为 t1 中 c1、c2 列创建统计信息 create stats t1(c1, c2); -- 为所有表创建统计信息,并使用自动选择收集策略 create stats *.* with statistics_enable_smart_policy=1; -- 为 t1 创建统计信息,并使用手动选择收集策略,强制使用 fullscan -- 若不强制全量扫描,统计信息的生成逻辑将由参数 statistics_enable_sample 控制 create stats t1 with fullscan -- 为所有库的所有表创建统计信息时,按 0.01 比例采样(采样行数取 统计参数 statistics_sample_row_count 与 表总行数的 0.01 倍 的最大值) create stats *.* with sample 0.01 ratio; -- 为所有库的所有表创建统计信息时,按 0.01 比例采样(采样行数取 40000000 与 表总行数的 0.01 倍 的最大值) create stats *.* with sample 0.01 ratio 40000000 rows; -- 按默认配置采样创建所有库所有表的统计信息 -- 采样规则由参数 statistics_sample_row_count(统计采样行数)和 statistics_sample_ratio(统计采样比例)控制 create stats *.* with sample;
SHOW (STATS|COLUMN_STATS) (<db>.* | *.* | [<db>.]<table>'('<col1>, <col2>, ..., <coln> ')' )
参数 | 是否必填 | 配置说明 |
|---|---|---|
| 否 | 选择此参数将显示表级统计信息,包括表的基本元数据信息。 |
| 否 | 选择此参数将显示列级统计信息,包括每列的详细数据分布信息。 |
| 否 | 指定数据库中的所有表。格式为: |
| 否 | 指定当前环境中的所有数据库和表。 |
| 否 | 指定特定的表。可选项包含数据库名,格式为: |
| 否 | 指定表中的特定列。格式为: |
DROP STATS (<db>.* | *.* | [<db>.]<table>['(' <col1>, <col2>, ..., <coln> ')' ])
参数 | 是否必填 | 配置说明 |
|---|---|---|
| 是 | 核心命令,用于删除统计信息。 |
| 否 | 指定数据库中的所有表。格式为: |
| 否 | 指定当前环境中的所有数据库和表。 |
| 否 | 指定特定的表。可选项包含数据库名,格式为: |
| 否 | 指定表中的特定列。格式为: |
对于数据工程师而言,通过执行计划诊断问题是很重要的排障手段。例如 Join order 的问题,统计信息是否缺失,估算是否合理,下推是否生效等等。ByteHouse 提供展示物理执行计划能力,用 Explain + Query 的方式对执行进行分析,便于更加直观地对查询进行分析和优化,并配合 Query Profiler 查询详情进行可视化展示。执行计划的详情请参见执行计划 EXPLAIN。
注意
当前需要先手动收集统计信息后,再生成执行计划。
生成物理执行计划:
EXPLAIN (QUERY Statement) ;
注意
当前 EXPLAIN 语义仅支持 DQL SELECT 语法的分析。
创建数据库表
CREATE DATABASE sampledb; CREATE TABLE sampledb.t1 ( id Int64, name Int64 ) ENGINE = CnchMergeTree() ORDER BY id; CREATE TABLE sampledb.t2 ( uid Int64, name Int64 ) ENGINE = CnchMergeTree() ORDER BY uid;
插入样例数据。
INSERT INTO sampledb.t1 VALUES (1,'bob'),(2,'alice'),(3,'peter'),(4,'jay'),(5,'yiyang'),(6,'aurora'); INSERT INTO sampledb.t2 VALUES (1,'smith'),(2,'parker'),(3,'taylor'),(4,'davis'),(5,'joines');
收集表的统计信息。
CREATE stats sampledb.t1; CREATE stats sampledb.t2;
展示如下结果:
table_name | row_count | elapsed_time |
|---|---|---|
t1 | 6 | 0.026777215 |
展示表的统计信息。
SHOW stats sampledb.t1;
为数据表生成执行计划。
USE sampledb; EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.uid);
将展示如下信息:
Gather Exchange est. 6 rows └─ Projection est. 6 rows │ Expressions: [id, name, uid], t2.name:=name_1 └─ Inner Join est. 6 rows │ Condition: id == uid ├─ Local Exchange est. 6 rows │ └─ ReadFromStorage 2100069045.sampledb.t1 est. 6 rows │ Outputs: [id, name] └─ Broadcast Exchange est. 5 rows └─ ReadFromStorage 2100069045.sampledb.t2 est. 5 rows Outputs: [uid], name_1:=name
删除表的统计信息。
DROP stats sampledb.t1; DROP stats sampledb.t1;