ByteHouse 优化器为业界目前唯一的 ClickHouse 优化器方案。ByteHouse 优化器的能力简单总结如下:
RBO:支持:列裁剪、分区裁剪、表达式简化、子查询解关联、谓词下推、冗余算子消除、Outer-JOIN 转 INNER-JOIN、算子下推存储、分布式算子拆分等常见的启发式优化能力。
CBO:基于 Cascade 搜索框架,实现了高效的 Join 枚举算法,以及基于 Histogram 的代价估算,对 10 表全连接级别规模的 Join Reorder 问题,能够全量枚举并寻求最优解,同时针对大于10表规模的 Join Reorder 支持启发式枚举并寻求最优解。CBO 支持基于规则扩展搜索空间,除了常见的 Join Reorder 问题以外,还支持 Outer-Join/Join Reorder,Magic Set Placement 等相关优化能力。
分布式计划优化:面向分布式MPP数据库,生成分布式查询计划,并且和 CBO 结合在一起。相对业界主流实现:分为两个阶段,首先寻求最优的单机版计划,然后将其分布式化。我们的方案则是将这两个阶段融合在一起,在整个 CBO 寻求最优解的过程中,会结合分布式计划的诉求,从代价的角度选择最优的分布式计划。对于 Join/Aggregate 的还支持 Partition 属性展开。
高阶优化能力:实现了 Dynamic Filter pushdown、单表物化视图改写、基于代价的 CTE (公共表达式共享)。
开启 ClickHouse SQL Mode:
set enable_optimizer =1
收集表中数据的直方图信息。目前暂未支持自动收集,因此需要手动触发。
-- Collect statistics for all tables in current database create stats all; -- Collect statistics for all tables and start sampling create stats all settings statistics_enable_sample = 1 -- Collect statistics of a table create stats [IF NOT EXISTS] <table_name>; -- Collect statistics of a table and start sampling create stats <table_name> settings statistics_enable_sample = 1
-- Display all statistics show stats all; -- Display Statistics of a table show stats [<db_name>.]<table_name>; -- Display column level statistics of all tables show column_stats all; -- Display specified column level statistics of specified table show column_stats [<db_name>.]<table_name> [at column <column_name>];
列的介绍:
identifier:表名.列名
type:列类型
Count:列中的值的总数量。
Null_count: 列中为空的字段的数据量。
NVD:列中不同值的数量。
Min:列中的最小值(如果是字符串类型,则?)。
Max:列中的最大值。
Has_histogram:是否已生成直方图。
-- Delete all statistics in current database drop stats all; -- Delete statistics of a table drop stats <table_name>;
set graphviz_path='/path/to/folder' use <database_name> show stats __save; # save statistics into /path/to/folder/<database_name>.bin show stats __load; # load statistics from /path/to/folder/<database_name>.bin
文件是PB格式的,请参考dbms/src/Protos/cbo_statistics.proto
.
支持 EXPLAIN
(返回执行计划,不执行)。
EXPALIN SELECT sum(l_extendedprice * l_discount) AS revenue FROM lineitem WHERE l_shipdate >= toDate('1994-01-01') AND l_shipdate < toDate('1994-01-01') + INTERVAL '1' YEAR AND l_discount BETWEEN toFloat64('0.06') - toFloat64('0.01') AND toFloat64('0.06') + toFloat64('0.01') AND l_quantity < 24
set print_graphviz=1 set graphviz_path='/.../...' (A path you can access on the server)
暂时无法在飞书文档外展示此内容
(后续可视化将作为产品功能提供)
如果性能回退,可以在 query_level 手动指定 SETTINGS enable_optimizer=0
--Add "SETTINGS enable_optimizer=0" after your query to turn off optimizer select distinct d_year from date_dim SETTINGS enable_optimizer=0;