400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
YMatrix 文档
关于 YMatrix
标准集群部署
数据写入
数据迁移
数据查询
运维监控
参考指南
工具指南
数据类型
存储引擎
执行引擎
系统配置参数
SQL 参考
常见问题(FAQ)
新架构 FAQ
集群部署 FAQ
SQL 查询 FAQ
MatrixGate FAQ
运维 FAQ
监控告警 FAQ
PXF FAQ
PLPython FAQ
性能 FAQ
这一小节会讨论如何高效地使用向量化执行引擎。
首先,对于不同的场景,向量化执行引擎相比传统的面向行的执行引擎,性能的提升是不同的,对此,你可以通过概述部分有一个基本的认识和理解。
例如,能够完全顺序操作的算子,比如一般地表达式计算、选择算子和聚集算子,能够最大程度得到性能提升。而对于引入了随机性的算子,比如排序算子(Sort)、哈希算子(Hash),则性能提升空间有限。
你需要尽可能使用原始类型(Primitive type),如 int32, int64 等,来提高向量化的性能提升效率。
一般枚举类型字段往往用于过滤操作,比如国家字段或中国省份字段,可以使用字符串表示,如"China"、"USA",或 "Beijing"、"Xinjiang" 等,但是如果预处理一下,使用 smallint 表示,那么对于过滤操作将会有巨大的性能提升。
如果数据中的年龄字段用 smallint 表示就足够了,那么就不需要使用 int32 甚至 int64 来表示。
对于传统的执行引擎,不管数值类型是什么,最后结果中的元组(Tuple)中往往是用 Datum 来表示处理,占用 64bits。Datum 可以表示任何 SQL 数据类型的单个值,但其本身不包含任何有关数据类型的信息。所以使用不同类型对于处理速度没有影响。
但是对于向量化执行引擎,数据是连续紧密布局的。数值类型越短,对于 CPU 缓存更友好,SIMD 寄存器也能存储更多数据。所以对某一列进行过滤或者聚集,类型使用 int64 会比 int16 慢四倍。
注意!
由于时间和资源受限,我们并没有实现所有数据库标准支持的数据类型、表达式和查询,但为了保证可用性,当遇到无法支持的情况时,我们会部分或者全部使用传统的执行引擎进行运算,现象体现为性能提升不明显或者没有提升。
你可以手动关闭 matrix.enable_mxv_fallback_expression
参数以确定查询是否使用了传统的执行引擎,此参数默认开启。
参数 | 描述 |
---|---|
matrix.enable_mxv_fallback_expression | 对于当前向量化执行引擎不能处理的表达式,是否要回退到传统执行引擎执行,默认开启 |
$ SET matrix.enable_mxv_fallback_expression TO off;
当 matrix.enable_mxv_fallback_expression
处于关闭状态且遇到如下错误,那么说明查询中包含当前版本向量化引擎无法处理的数据类型、表达式或者查询。
$ not implemented yet
Hash Agg 和 Group Agg 是聚集算子的两种具体实现,有各自的适用场景。Hash Agg 使用哈希表实现聚合,Group Agg 对分组后数据进行聚合。
通常情况下,优化器根据统计信息能够针对查询选择合适的算子。但是如果统计信息不准确或者对查询优化不足,可能会选择一个非最优的路径。这里介绍两个 GUC 帮助分析优化查询。
参数 | 描述 |
---|---|
matrix.enable_mxv_aggregate | 用于控制是否开启 Group Agg 功能,默认开启 |
matrix.enable_mxv_hash_aggregate | 用于控制是否开启 Hash Agg 功能,默认开启 |
两两组合共计四种可能性。
matrix.enable_mxv_aggregate
且关闭 matrix.enable_mxv_hash_aggregate
,那么强制使用 Group Agg 聚集实现;matrix.enable_mxv_hash_aggregate
且关闭 matrix.enable_mxv_aggregate
,那么强制使用 Hash Agg 聚集实现。在 MARS2 和 MARS3 中,数据都是有序存储的。为了最大化利用顺序性带来的性能提升,最好选择经常使用且过滤效果好的字段作为排序键(即排序顺序涉及的字段)。比如设备监控表,可以采用事件时间戳和设备 ID 作为排序键。
MARS2 和 MARS3 的排序键均只能指定一次,不能修改,不能新增,不能删除。
不同的是,MARS2 在创建表时:
而 MARS3 在创建表时:
COLLATE C
能够加速排序。MARS2 可以通过如下 SQL 指定一组排序键:
=# CREATE TABLE t (
tag int,
ts timestamp,
name text,
region int
) USING MARS2;
=# CREATE INDEX ON t USING mars2_btree (ts, tag);
MARS3 可以通过如下 SQL 指定一组排序键:
=# CREATE TABLE t (
tag int,
ts timestamp,
name text,
region int
) USING MARS3
ORDER BY (ts, tag);
对于 MARS2 和 MARS3 而言,排序键的选择对于查询的性能都至关重要,数据有序不仅能够加速数据的扫描和存储引擎的块筛选,而且对于排序、聚集也有所帮助。
例如,我们指定某表的排序键为 (c1,c2)
,那么其内部数据按照 (c1,c2)
有序。现在我们想执行以下两种只涉及排序操作的查询语句:
=# SELECT * FROM t ORDER BY c1, c2;
=# SELECT * FROM t ORDER BY c1, c3;
第一个查询不再需要排序,向量化执行引擎会优化掉排序算子。对于第二个查询,c1 已经有序了,那么向量化执行引擎会对这种情况有特殊优化,仅对相同 c1 的不同 c3 进行排序。
只涉及聚集的查询:
=# SELECT sum(c1), sum(c2) FROM t GROUP BY c1, c2;
=# SELECT sum(c1), sum(c3) FROM t GROUP BY c1, c3;
如果使用 Group Agg,那么类似于排序,能够大幅提升性能,只需要顺序扫描数据进行聚集操作即可。对于 Hash Agg,数据是否有序对性能几乎没有影响。如前所述,对于顺序算子向量化执行引擎能最大程度发挥其性能,所以针对上面两个查询,尤其是第一个,使用 Group Agg 往往耗时更低。
综上,需要分析和结合业务,根据查询的特征(需要排序、聚集、过滤的列)来选择排序键。
根据排序键,MARS2、MARS3 中存储的数据都是有序的,一段连续有序的数据称为 Run。Run 的元信息存储了最小最大值,用于在查询时进行过滤。因为是通过元信息进行过滤,不需要加载数据本身,相比于顺序扫描(先访问数据本身,再进行过滤)其 I/O 开销更低,能更快的进行过滤。
下面分别举例:
对于 MARS2 表,示例 DDL 的所有列上都建立了 minmax 索引(实际工作中可以根据需要建立)。
=# CREATE TABLE t (
tag int encoding (minmax),
ts timestamp encoding (minmax),
name text encoding (minmax),
region int encoding (minmax)
) USING MARS2;
=# CREATE INDEX ON t USING mars2_btree(tag);
对于 MARS3 表,创建 Brin 索引示例 DDL 如下:
=# CREATE INDEX idx_mars3 ON t USING mars3_brin(ts, tag);
我们想要从上述 MARS2(或 MARS3)表查询今年某个区域的数据:
=# SELECT * FROM t WHERE ts > '2022-01-01' AND region = 2;
实际上,minmax 索引(Brin 索引)不仅能够使得存储引擎进行块筛选,还能够加速向量化执行引擎的计算。
从存储引擎的角度看,如果一个块(包含某列数据的若干行)的 ts
上最大值小于 2022-01-01
,那么存储引擎不再读取这一块,节省 I/O 资源,同时,也减少了引擎的计算量。
向量化执行引擎会利用 minmax (Brin)信息加速计算。比如某块 Region 的最大值和最小值都是 2
,那么执行引擎只会在该块应用谓词 ts > '2022-01-01'
过滤出符合条件的数据,而不会进行任何和 Region 有关的运算,提高性能。
minmax 索引(Brin 索引)和排序键是独立设置的,前者可以用于所有列,而后者往往只会选择几列。对于过滤、排序等算子的影响不尽相同,但也有交叉,所以可以综合考虑使用这两者以发挥各自长处。
MARS2、MARS3 均提供了索引扫描,但是当前版本的向量化执行引擎只对接了 minmax 索引(Brin 索引)及顺序扫描,没有和索引扫描对接,那么对于一些查询,虽然开启了向量化执行引擎的开关,但是没有使用向量化执行引擎。计划中会出现 Custom Scan (sortheapscan)
字样。
此时,可以通过禁用索引扫描以使用向量化执行引擎。
$ SET enable_indexscan TO off;
MARS2、MARS3 更多详细信息请见 存储引擎