holo3:Event Time Column(Segment Key)聚簇索引Clustering Key

holo3:Event Time Column(Segment Key)聚簇索引Clustering Key_第1张图片
Event Time Column介绍
Event_time_column原名为Segment Key,在Hologres V0.9版本默认改名为Event_time_column,Segment Key依旧向下兼容使用。

Segment Key主要适用的场景如下:

含范围过滤条件(包括等值条件)的查询场景。

基于主键的UPDATE。

BEGIN;
CREATE TABLE <table_name> (...);
call set_table_property('', 'event_time_column', '[ [,...]]');
COMMIT;

使用建议

Event_time_column适用于数据为单调递增或单调递减的有序字段,例如时间戳字段。非常适用于日志、流量等和时间强相关的数据,合理设置可极大提升性能。完全无序的Event_time_column会导致合并之后每个文件缺乏区分度,达不到任何文件过滤效果。

如果表不存在明显的单调递增或单调递减的字段,可以选择额外扩充一列update_time,每次UPSERT时将当前时间写入该新增字段。

Event_time_column具备左匹配原则,因此不建议将多个字段设置为Event_time_column,否则使得查询场景受限,达不到加速效果,一般情况建议选择设置两个或者两个以内字段设置为Event_time_column。
Segment Key可以对以下场景进行加速:

含范围过滤条件(包括等值条件)的查询场景。

如果查询字段设置为Segment
Key,那么Hologres在扫描数据时,会将范围查询条件同文件内列的统计信息(min/max)进行匹配,快速过滤出所需的文件,加速查询。

基于主键的UPDATE。

Hologres的UPDATE命令原理是由DELETE命令和INSERT命令组合实现。在基于主键的UPDATE或INSERT ON
CONFLICT(UPSERT)场景中,会先根据主键找到目标表(旧数据)的Segment Key值,再根据旧数据的Segment
Key找到旧数据所在文件,最终定位旧数据所在位置进而标记为DELETE。如果设置了合理的Segment
Key,那么就会快速定位到旧数据的文件,提高写入性能。相反,如果这张列存表没有配置Segment Key、Segment
Key配置了不合理的字段或者Segment
Key对应的字段在写入时没有与时间有强相关性(比如基本乱序),那在查找旧数据时需要扫描的文件将会非常多,不仅会有大量的IO操作,而且会大量占用CPU,影响写入性能和整个实例的负载。


使用建议

Clustering Key主要适用于点查以及范围查询的场景,对于过滤操作有比较好的性能提升,即对于where a = 1或者where a

1 and a < 5的场景加速效果比较好。可以同时设置Clustering Key和Bitmap Column以达到最佳的点查性能。

Clustering Key具备左匹配原则,因此一般不建议设置Clustering
Key超过两个字段,否则适用场景受限。Clustering Key是用于排序,所以Clustering
Key里的列组合是有先后关系的,即排在前面列的排序优先级高于后面的列。

指定Clustering Key字段时,可在字段名后添加:asc来构建索引时的排序方式。排序方式默认为asc,即升序。Hologres
V2.1以前版本不支持设置构建索引时的排序方式为降序(desc),如果设置了降序,无法命中Clustering
Key,导致查询性能不佳;从V2.1版本开始,开启如下GUC后支持设置Clustering
Key为desc,但仅支持Text、Char、Varchar、Bytea、Int等类型的字段,其余数据类型的字段暂不支持设置Clustering
Key为desc。

set hg_experimental_optimizer_enable_variable_length_desc_ck_filter
= on; 对于行存表,Clustering Key默认为主键 (Hologres V0.9之前版本默认不设置)。如果设置和主键不同的Clustering Key,那么Hologres会为这张表生成两个排序(Primary
Key排序和Clustering Key排序),造成数据冗余。

holo3:Event Time Column(Segment Key)聚簇索引Clustering Key_第2张图片
技术原理
在这里插入图片描述

Bitmap不同于Distribution Key和Clustering
Key,Bitmap是数据存储之外的独立索引,设置了Bitmap索引之后,系统会将列对应的数值生成一个二进制字符串,用于表示取值所在位置的Bitmap,当查询命中Bitmap时,会快速定位到数据所在的行号(Row
Number),从而快速过滤出数据。但Bitmap并不是没有开销的,对于以下场景需要注意事项如下:

列的基数较高(重复数据较少)场景:假如列的基数较高,那么就会为每一个值生成一个Bitmap,当非重复值很多的时候,就会形成稀疏数组,占用存储较多。

大宽表的每一列都设置为Bitmap场景:如果为大宽表的每一列都设置为Bitmap,那么在写入时每个值都需要构建成Bitmap,会有一定的系统开销,从而影响写入性能。

综上,Bitmap本质上是空间换时间的手段,对于数据分布比较均匀的列有比较高的性价比。

Bitmap和Clustering Key的区别 相同点: Bitmap和Clustering Key都是文件内的数据过滤。 不同点:
Bitmap更适合等值查询,通过文件号定位到数据;Clustering Key是文件内的排序,因此更适合范围查询。 Clustering
Key的优先级会比Bitmap更高,即如果为同一个字段设置了Clustering
Key和Bitmap,那么优化器会优先使用Clustering Key去匹配文件

常见问题 导入MaxCompute的数据至Hologres时发生OOM(Out Of
Memory,内存溢出),提示超出内存限制异常。通常会产生Query executor exceeded total memory
limitation xxxxx: yyyy bytes used报错。导致报错的四种可能原因及其对应的解决方案如下所示。 排查步骤一
可能原因:
当导入query包含查询,但部分table没有analyze;或者进行过analyze,但数据又有更新导致不准确,最终导致查询优化器决策join
order有误,引起内存开销过高。 解决方案: 对所有参与的内表、外表执行analyze
命令,更新表的统计元信息,可以帮助查询优化器生成更优的执行计划,解决出现OOM的情况。 排查步骤二 可能原因:
当表的列数较多,单行数据量较大时,单次读取的数据量会更大,引起内存开销过高。 解决方案:
在sql语句前加以下参数来控制单次读取数据行数,可以有效减少OOM情况。 set
hg_experimental_query_batch_size = 1024;–默认为8192 insert into
holo_table select * from mc_table; 排查步骤三 可能原因:
导入数据的过程中,并发度高,CPU消耗大,影响内表查询。 解决方案:
在V1.1之前版本,可以通过并发度通过参数hg_experimental_foreign_table_executor_max_dop控制,默认为实例的Core数,在导入时设置更小的hg_experimental_foreign_table_executor_max_dop参数,降低导入的内存使用,解决出现OOM的情况。该参数对外表执行的所有作业有效。代码示例如下所示。
set hg_experimental_foreign_table_executor_max_dop = 8; insert into
holo_table select * from mc_table; 排查步骤四 可能原因:
导入数据的过程中,并发度高,CPU消耗大,影响内表查询。 解决方案:
从V1.1版本开始,可以通过并发度参数hg_foreign_table_executor_dml_max_dop控制,默认为32,在导入时设置更小的hg_foreign_table_executor_dml_max_dop参数,降低执行DML语句的并发度(主要是数据导入导出场景),避免执行DML语句占用过多资源。代码示例如下所示。
set hg_foreign_table_executor_dml_max_dop = 8; insert into holo_table
select * from mc_table;

你可能感兴趣的:(java,数据库,前端)