在ClickHouse中,存储的数据会按主键进行排序。这其实是创建了一个稀疏索引,从而可以加快数据的查询。本文介绍ClickHouse主键的作用,和排序键的关系。
主键的作用定义主键时,列的数量并没有明确的限制,主键可以包含一列或多列。主键的作用主要有:
改善索引的性能
如果当前主键是 (a, b)
,在下列情况下添加另一个 c
列会提升性能:
查询会使用 c
列作为条件
很长的数据范围( index_granularity
的数倍)里 (a, b)
都是相同的值,并且这样的情况很普遍。也就是说,就是加入另一列后,可以让您的查询跳过很长的数据范围。
改善数据压缩
ClickHouse 以主键排序片段数据,所以,数据的一致性越高,压缩越好。
在CollapsingMergeTree 和 SummingMergeTree 引擎里进行数据合并时会提供额外的处理逻辑
在这种情况下,指定与主键不同的 排序键 也是有意义的。
长的主键会对插入性能和内存消耗有影响,但主键中额外的列并不影响 SELECT
查询的性能。
可以使用 ORDER BY tuple()
语法创建没有主键的表。在这种情况下 ClickHouse 根据数据插入的顺序存储。如果在使用 INSERT ... SELECT
时希望保持数据的排序,可以设置 max_insert_threads = 1。
主键是在创建表时,通过PRIMARY KEY指定的,可以通过两种方式指定主键:
在列表内指定CREATE TABLE db.table_name
(
name1 type1, name2 type2, ...,
PRIMARY KEY(expr1[, expr2,...])]
)
ENGINE = engine;
在列表外指定
CREATE TABLE db.table_name
(
name1 type1, name2 type2, ...
)
ENGINE = engine
PRIMARY KEY(expr1[, expr2,...]);
注意:
创建主键会自动为主键的列创建索引;ClickHouse 不要求主键唯一,所以可以插入多条具有相同主键的行;使用索引通常会比全表描述要高效。 主键和排序键(oder by) 创建表时,一般不需要指定主键,只要指定排序键即可。当没有指定主键(primary key)时,会把order by后面的列作为主键。可以同时指定排序键(order by)和主键(primary key),但主键最好是排序键的前缀。当指定的主键和排序键不同时:
此时排序键用于在数据片段中进行排序,主键用于在索引文件中进行标记的写入。主键表达式元组必须是排序键表达式元组的前缀,即主键为(a,b),排序列必须为(a,b,******)。 小结通过以上分析可知:
在创建表时指定主键,会根据主键创建索引;主键可以是多个列,不会影响查询性能,而且主键相同的数据可以重复;一般不指定主键(primary key),而是指定排序键(order by),此时会把排序键作为主键;排序键和主键可以不同,但此时主键必须时排序键的前缀。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)