You need to enable JavaScript to run this app.
导航
Paimon 查询优化
最近更新时间:2025.03.28 15:32:06首次发布时间:2025.03.28 15:32:06
我的收藏
有用
有用
无用
无用

概览

Paimon 作为实时数据湖,除了支持 Flink 和 Spark 引擎外,同样支持 ByteHouse、Trino、Presto、Doris/StarRocks 等丰富的 OLAP 产品作为查询引擎。得益于 Paimon 的 LSM-Tree 结构设计,往往 OLAP 引擎查询 Paimon 数据湖会有很好的主键查询性能。本文主要介绍 Paimon 的查询优化常见的概念和手段。

表模式

Paimon 表类型分为主键表和非主键表(Append)表。

非主键表类似于传统的 Hive 表,没有主键设置。值得注意的是,Paimon 的 Append 表在 checkpoint 提交数据。这种强一致性保证,不会因为 Paimon 任务 checkpoint 失败而导致数据丢失或者重复,可以达到 Exactly-Once。

主键表的文件结构大致如下所示,表或分区包含多个桶(bucket),每个桶是一个独立的 LSM 树结构,包含多个文件。LSM 的写入过程大致如下:Flink checkpoint 会刷新 L0 文件,并根据需要触发 compaction 以合并数据。根据写入时的处理方式不同,有以下三种模式:

  • MOR (Merge On Read):默认模式,仅执行 minor compaction,读取时需要合并。
    • 写入性能:非常好。
    • 查询性能:不太好(每个 Bucket 仅支持一个合并线程)。
  • COW (Copy On Write):使用'full-compaction.delta-commits' = '1',同步进行 full compaction,即在写入时完成合并。
    • 写入性能:非常差(每次写入都要执行 Compact)。
    • 查询性能:非常好。
  • MOW (Merge On Write):使用'deletion-vectors.enabled' = 'true',在写入阶段,LSM 会查询并生成数据文件的 deletion vector 文件,在读取时直接过滤掉不必要的行。
    • 写入性能:好。
    • 查询性能:好。

表模式对查询性能的影响非常大。一般情况下,主键表为了较好的查询性能,比较推荐使用 MOW(即开启 Deletion Vector)表。大致几种表特点如下:

  1. 写入资源消耗(主要在于 Compact 消耗,越小约好):
    1. Append < MOR < MOW < COW。
  2. 查询性能(越大越好):
    1. 主键点查性能:COW > MOW > MOR > Append。
    2. 过滤 + Scan/聚合性能:COW > MOW > Append > MOR。

查询性能优化

通过主键过滤进行数据跳过

对于常规的分桶表(例如,bucket = 5),主键的过滤条件将大大加速查询并减少大量文件的读取。所以可以如果是经常性通过主键进行点查,所以合理设计主键字段是非常有效的选择。
另外主键采取前缀索引的方式,所以设计主键索引的时候,尽量将可能单独查询的字段放在前面。比如 region + userid 作为主键,如果 region 是一定会带有的查询条件,而 userid 不会作为单独的查询条件进行查询的话,就建议主键定义 region 在 userid 之前。

开启 Deletion Vector

Deletion Vector 在主键表场景下,通过记录指定文件中的记录需要被 Delete 的记录(比如主键表 Insert 记录时查询已有主键,如有则需在 Deletion Vector 文件中记录)。
基于上述的 Merge On Write,所以在 Read 阶段无须在进行 Merge,只需要综合 Data 文件 + Deletion Vector 的结果,实现并发不再受限于 Bucket 数量,最高可到文件数量,极大提高 OLAP 读取效率;

通过文件索引进行数据跳过

您可以在启用 Deletion Vectors 的表中使用文件索引。Paimon 的 Data File 支持创建对应的 File Index 文件,当前 Paimon 版本支持 Bloom Filter,可以快速判断某个文件中是否包含某个字段值,显著提高对应列值在 Data File 中的 SCAN 效率;

CREATE TABLE <PAIMON_TABLE> WITH (
    'deletion-vectors.enabled' = 'true',
    'file-index.bloom-filter.columns' = 'c1,c2',
    'file-index.bloom-filter.c1.items' = '200'
);

支持的过滤器类型:
Bloom Filter

  • file-index.bloom-filter.columns:指定需要 Bloom Filter 索引的列。
  • file-index.bloom-filter.<column_name>.fpp:配置误报率。
  • file-index.bloom-filter.<column_name>.items:配置一个数据文件中预期的不同项的数量。

结合业务场景使用 Append 表

因为 Flink Paimon 的 Checkpoint 提交机制,可以保证写入 Paimon Append 表数据不丢失不重复。所以如果业务中如果没有主键去重需求的时候,可以不用担心 Flink Failover 引入重复数据。
在大部分情况下,Append 表可以大幅提升写入性能,也因不受并行度限制,也可以保障较好的查询性能。但因为 Append 表底层无序的,所以通过主键字段范围查询、点查性能还是比主键表要弱。

优化表查询

如果您需要极致的读取性能,并且可以接受读取略微过时的数据,您可以使用ro读优化表 (Read-optimized Table))系统表。读取优化的系统表通过仅扫描不需要合并的文件来提高读取性能。
对于主键表,ro系统表仅扫描最顶层的文件。也就是说,ro系统表仅生成最新 Full Compaction 的结果。由于不同的存储桶可能在不同的时间执行 Full Compaction,因此不同键的值可能来自不同的快照。
对于追加表,由于所有文件都可以在不合并的情况下读取,ro系统表的行为与普通的追加表类似。

SELECT * FROM my_table$ro;