表分区片段
在 ClickHouse 中,表分区是什么?
ClickHouse MergeTree 引擎系列 中每个表的数据在磁盘上组织为不可变的 data parts 集合。
为了说明这一点,我们使用 此 表(改编自 英国房产价格数据集),跟踪在英国售出房产的日期、城镇、街道和价格:
您可以在我们的 ClickHouse SQL Playground 中 查询此表。
当一组行插入到表中时,会创建一个数据分区。以下图示说明了这一点:

当 ClickHouse 服务器处理上面图中勾勒的 4 行示例插入(例如,通过 INSERT INTO 语句)时,它会执行几个步骤:
① 排序:行按表的 ^^sorting key^^ (town, street) 进行排序,并为排序后的行生成一个 稀疏主索引。
② 拆分:排序后的数据被拆分为列。
③ 压缩:每一列被 压缩。
④ 写入磁盘:压缩后的列作为二进制列文件保存在一个新目录中,该目录表示插入的数据分区。稀疏主索引也被压缩并存储在同一目录中。
根据表的具体引擎,排序期间还可能发生其他转换 可能。
数据 ^^parts^^ 是自包含的,包括解释其内容所需的所有元数据,无需中央目录。除了稀疏主索引,^^parts^^ 还包含其他元数据,例如次要 数据跳过索引、列统计信息、校验和、最小-最大索引(如果使用了 分区)以及 更多。
分区合并
为了管理每个表的 ^^parts^^ 数量,后台合并 任务会定期将较小的 ^^parts^^ 合并为较大的 ^^parts^^,直到它们达到可配置的 压缩大小(通常约为 150 GB)。合并后的 ^^parts^^ 被标记为非活动,并在 可配置 时间间隔后被删除。随着时间的推移,该过程创建了一个合并的 ^^parts^^ 层次结构,这就是为什么它被称为 ^^MergeTree^^ 表:

为了最小化初始 ^^parts^^ 的数量和合并的开销,数据库客户端被 鼓励 要么批量插入元组,例如一次 20,000 行,要么使用 异步插入模式,在该模式下 ClickHouse 会将来自多个传入 INSERT 的行缓冲到同一表中,并仅在缓冲区大小超过可配置阈值或超时到期后创建新分区。
监控表分区
您可以通过使用 虚拟列 _part 来 查询 我们示例表中所有当前存在的活动 ^^parts^^ 列表:
上述查询检索磁盘上的目录名称,每个目录代表表的一个活动数据分区。这些目录名称的组件具有特定含义,对于有兴趣进一步探索的人可以在 这里 找到相关文档。
或者,ClickHouse 会在 system.parts 系统表中跟踪所有表的所有 ^^parts^^ 的信息,以下查询 返回 我们示例表中所有当前活动 ^^parts^^ 的列表、它们的合并级别以及存储在这些 ^^parts^^ 中的行数:
每次在分区上进行额外合并时,合并级别递增 1。级别 0 表示这是一个尚未合并的新分区。