本文介绍云数据库ClickHouse22.8版本推出的新特性。
日期和时间类型扩展
扩展
Date32
和DateTime64
类型,将日期支持范围从之前版本的1925年~2283年,扩展到1900年~2299年。日期类型数据精度最大为8位,达到微秒级精度。超出最大时间精度后支持的时间范围会缩小,只支持到2262-04-11。
轻量级删除
22.8版本MergeTree引擎表支持标准的DELETE FROM SQL
语法,同时实现了轻量级删除的逻辑。在之前版本中,云数据库ClickHouse的DELETE操作是Mutation类操作,所有的DELETE事件都是先通过文件进行单独记录存储,然后再基于内核调度不定时的异步执行,另外执行过程也比较复杂,需要定位到相应的记录,进行实际的物理删除。
旧版本的DELETE
语法如下:
ALTER TABLE [db.]table [ON CLUSTER cluster] DELETE WHERE filter_expr
新版本的DELETE
语法如下:
DELETE FROM [db.]table [WHERE expr]
示例如下:
DELETE FROM hits WHERE Title LIKE '%hello%' ;
关于LIKE
表达式的更多信息,请参见LIKE。
标准SQL语法的支持,相比较之前的Mutation类操作方式,增强了开发的便利性。根据官方的性能测试结果,在单表1亿记录总量,110个数据分区规模下,轻量级删除的性能较之前版本提升了近40倍左右,性能提升明显。但当前DELETE
语法的实现仍然默认是异步执行。其内部基于ClickHouse的列更新机制,在数据分区中增加了系统虚拟列“_row_exists”,通过update_row_exists=0 where predicate
来标记行是“已删除”状态。
支持JSON类型和动态子列
老版本的JSON格式数据读写方式
在22.8之前的版本中,ClickHouse支持以String类型来存储JSON对象,因为JSON对象是文本格式,需要通过特殊的String解析函数来解析复杂的JSON结构,从而获得JSON对象内部字段信息。这种String类型存储方式,内部多个字段混合存储,针对内部特定属性的查询会带有额外的字段扫描消耗,因此查询效率非常低。同时使用起来也比较麻烦,如果JSON数据存在多层嵌套,那么查询JSON数据就需要一层层去进行解析和类型转换,才能被业务使用。示例如下:
CREATE TABLE games (data String)
ENGINE = MergeTree ORDER BY tuple();
SELECT JSONExtractString(data, 'teams', 1, 'name')
FROM games;
新版本的JSON数据读写方式
新版本中推出了独立JSON对象类型,DDL操作时JSON对象只需要指定JSON类型即可。同时引擎针对每个写入的JSON对象值进行动态类型匹配,每个JSON属性按照独立列进行存储。当新写入的JSON对象值和之前的类型不匹配时,引擎会动态修改列类型来兼容所有的数据类型,对于新增JSON属性也会动态增加新的列进行数据的存储。示例如下:
DROP TABLE IF EXISTS github_JSON;
SET allow_experimental_object_type=1;
CREATE table github_JSON(event JSON) ENGINE = MergeTree ORDER BY tuple()
动态子列的支持,大幅提高了非结构化数据的分析效率和扩展性。
对于常见的导入OSS数据到ClickHouse,在22.8之前版本中如果要实现JSON对象子列的独立存储和高效分析,那么就必须预先在ClickHouse建立结构化的目标表,并明确定义每个字段的数据类型,才能将半结构化的JSON数据写入到ClickHouse中。如果JSON对象结构变更,那么需要同时修改目标表的表结构,才能适配写入。
而新版本中由于有了动态子列,开发者完全不需要关心JSON的嵌套层次和内部数据类型,只需要在目标表中创建JSON数据类型字段,直接将半结构化的数据批量导入到ClickHouse目标表中即可。同时在业务变更JSON对象属性增加的情况下,也不需要修改目标表的结构,内核会动态增加子列,并进行数据存储,扩展灵活度大幅提升。示例如下:
INSERT INTO github_JSON SELECT * FROM OSS('oss-endpoint',
JSONAsObject, 'event JSON');
读取数据时不需要按照字符串进行解析和类型转换,可直接基于JSON对象进行属性的嵌套读取。动态子列的支持大大提升了JSON类型数据的存储和查询效率。根据社区官方的测试结果,新版本JSON对比老版本String整体查询效率提升了40倍左右。示例如下:
SELECT event.type, event.repo, event.actor FROM github_JSON LIMIT 1;
远程文件系统的本地缓存
当ClickHouse从本地磁盘文件系统读取数据时是非常快的,例如阿里云ECS本地盘或者云盘上的数据被OSS缓存在Page Cache中再进行读取。但是,如果ClickHouse从远程文件系统(例如OSS)读取数据,则系统不会感知到这些读取,且无法使用Page Cache。在22.8版本中,ClickHouse内核层面实现了引擎级别的远程文件系统的缓存,缓存同时使用本地磁盘和RAM,极大地提高了性能。
云数据库ClickHouse云原生版基于对象存储OSS实现了基于多计算节点共享存储的存算分离架构,通过应用引擎的缓存能力保证了云原生版本的查询性能。
其他特性
22.8版本除了以上的重要的特性发布之外,还带来一些其他特性,例如:
Projection:源表数据的一致性增强。同时基于“空间换效率”的逻辑,创建基于不同排序索引维度的物理表,数十倍地提高了非排序键数据的查询效率。
用户自定义函数:支持SQL模式和脚本模式的用户自定义函数,提高了用户自主进行数据清洗和处理的能力。