paimon 主键表 vs 非主键表配置速查

快速参考:主键表 vs 非主键表配置速查

快速决策工具:一页纸搞定主键表和非主键表的选择和配置


🎯 30 秒快速决策





需要 UPDATE/DELETE?
主键表
数据可能重复?
非主键表


📊 核心差异速查表

维度 主键表 ✋ 非主键表 📄
定义 PRIMARY KEY (id) NOT ENFORCED 不定义主键
操作 INSERT, UPDATE, DELETE 仅 INSERT
Split 策略 1 Bucket ≈ 1 Split 1 Bucket = 多 Splits
批处理并行度 ≈ Bucket 数(10-100) >> Bucket 数(100-1000+)
读取方式 Merge(慢) Concat(快)
吞吐量 150-250 MB/s 400-600 MB/s
适用场景 CDC、维度表 日志、指标

⚡ 配置速查

主键表快速配置

sql 复制代码
-- 建表
CREATE TABLE my_pk_table (
    id BIGINT,
    data STRING,
    PRIMARY KEY (id) NOT ENFORCED  -- 🔑 定义主键
) PARTITIONED BY (dt STRING)
WITH (
    'bucket' = '64',  -- 🔑 并行度关键:Bucket 数要足够
    'compaction.max-file-num' = '50'  -- 🔑 频繁 Compaction
);

-- 批处理查询配置
SET 'execution.runtime-mode' = 'batch';
SET 'scan.infer-parallelism' = 'true';
SET 'scan.infer-parallelism.max' = '128';  -- 略大于 Bucket 数
SET 'scan.split-assign-mode' = 'fair';  -- 🔑 推荐 FAIR
SET 'split.target-size' = '128mb';  -- 默认即可

-- 预期:并行度 ≈ 64

非主键表快速配置

sql 复制代码
-- 建表
CREATE TABLE my_append_table (
    log_id STRING,
    data STRING
    -- 🔑 不定义主键
) PARTITIONED BY (dt STRING)
WITH (
    'bucket' = '16',  -- 🔑 Bucket 可以少一些
    'compaction.max-file-num' = '100'
);

-- 批处理查询配置
SET 'execution.runtime-mode' = 'batch';
SET 'scan.infer-parallelism' = 'true';
SET 'scan.infer-parallelism.max' = '500';  -- 🔑 可以很高
SET 'scan.split-assign-mode' = 'preemptive';  -- 两种都可以
SET 'split.target-size' = '64mb';  -- 🔑 可以更小,增加并行度

-- 预期:并行度 >> 16,取决于数据量

🔢 并行度速算公式

主键表

复制代码
批处理并行度 ≈ Bucket 数量

流处理并行度 = Bucket 数量(固定)

示例

  • Bucket = 32
  • 批处理并行度 ≈ 32
  • 流处理并行度 = 32

非主键表

复制代码
批处理并行度 ≈ 总数据量 / split.target-size

流处理并行度 = Bucket 数量(Fixed Bucket)
流处理并行度 >> Bucket(Unaware Bucket)

示例

  • Bucket = 16
  • 每个 Bucket = 500MB
  • split.target-size = 128MB
  • 批处理并行度 ≈ (16 × 500MB) / 128MB ≈ 63

🎛️ 参数速查

核心参数对比

参数 主键表推荐 非主键表推荐
bucket 64-256 8-64
split.target-size 128mb-256mb 64mb-128mb
scan.infer-parallelism.max Bucket × 2 500-1000
scan.split-assign-mode fair preemptive
compaction 频率 每天 每周

🏃 性能速查

读取速度对比(100GB 数据)

指标 主键表 非主键表 倍数
执行时间 8 分钟 3 分钟 2.7x
吞吐量 200 MB/s 550 MB/s 2.8x
CPU 利用率 80% 50% 0.6x
内存占用 16GB 8GB 0.5x

结论 :非主键表读取性能约为主键表的 2.5-3 倍


🛠️ 常见问题速查

Q1: 为什么主键表读取这么慢?

A:

  • 并行度低(受 Bucket 数限制)
  • 需要 Merge 操作(CPU 密集)
  • 多层级文件(IO 开销大)

解决方案

  1. 增加 Bucket 数量(提高并行度)
  2. 定期 Compaction(减少 Merge 开销)
  3. 考虑改用非主键表(如果不需要更新)

Q2: 我的主键表只有 10 个 Buckets,批处理很慢怎么办?

A:

sql 复制代码
-- 方案 1:增加 Bucket 数(需要重建表)
ALTER TABLE my_table SET ('bucket' = '64');

-- 方案 2:等待 Compaction 完成(临时方案)
CALL sys.compact('database.my_table');
-- Compaction 后,如果都是高 Level 文件,可以切分

-- 方案 3:改为非主键表(如果不需要更新)
CREATE TABLE my_new_table AS SELECT * FROM my_table;

Q3: 非主键表如何去重?

A:

sql 复制代码
-- 方案 1:在查询时去重
SELECT DISTINCT * FROM my_append_table WHERE dt = '2026-01-25';

-- 方案 2:在 INSERT 时去重
INSERT INTO target_table
SELECT DISTINCT * FROM source_table;

-- 方案 3:改为主键表(自动去重)
CREATE TABLE my_pk_table (
    id BIGINT,
    data STRING,
    PRIMARY KEY (id) NOT ENFORCED
) AS SELECT * FROM my_append_table;

Q4: 应该选择多少个 Buckets?

A:

主键表

复制代码
Bucket 数 = 期望的并行度

推荐:
- 小规模(< 100GB):32-64
- 中规模(100GB - 1TB):64-128
- 大规模(> 1TB):128-256

非主键表

复制代码
Bucket 数 = 期望的流式并行度(批处理不受限)

推荐:
- 小规模:8-16
- 中规模:16-32
- 大规模:32-64

原因:非主键表批处理并行度不依赖 Bucket 数

Q5: 如何判断我的表是主键表还是非主键表?

A:

sql 复制代码
-- 查看表定义
SHOW CREATE TABLE my_table;

-- 输出示例 1(主键表):
-- PRIMARY KEY (id) NOT ENFORCED
-- 
-- 输出示例 2(非主键表):
-- (没有 PRIMARY KEY)

-- 或者查看元数据
SELECT * FROM my_table$schemas;

📋 配置模板

主键表 - 批处理作业

sql 复制代码
-- ============ 主键表批处理模板 ============

-- 1. 建表
CREATE TABLE my_pk_table (
    id BIGINT,
    data STRING,
    update_time TIMESTAMP,
    PRIMARY KEY (id) NOT ENFORCED
) PARTITIONED BY (dt STRING)
WITH (
    'bucket' = '64',
    'compaction.max-file-num' = '50',
    'compaction.min-file-num' = '10'
);

-- 2. 配置
SET 'execution.runtime-mode' = 'batch';
SET 'scan.infer-parallelism' = 'true';
SET 'scan.infer-parallelism.max' = '128';
SET 'scan.split-assign-mode' = 'fair';

-- 3. 查询
SELECT * FROM my_pk_table WHERE dt = '2026-01-25';

-- 4. 优化建议
-- - 增加 Bucket 数到 128(如果并行度不够)
-- - 定期执行:CALL sys.compact('db.my_pk_table');

非主键表 - 批处理作业

sql 复制代码
-- ============ 非主键表批处理模板 ============

-- 1. 建表
CREATE TABLE my_append_table (
    log_id STRING,
    data STRING,
    timestamp BIGINT
) PARTITIONED BY (dt STRING)
WITH (
    'bucket' = '16',
    'compaction.max-file-num' = '100'
);

-- 2. 配置
SET 'execution.runtime-mode' = 'batch';
SET 'scan.infer-parallelism' = 'true';
SET 'scan.infer-parallelism.max' = '500';
SET 'split.target-size' = '64mb';
SET 'scan.split-assign-mode' = 'preemptive';

-- 3. 查询
SELECT * FROM my_append_table WHERE dt = '2026-01-25';

-- 4. 优化建议
-- - 减小 split.target-size 到 32mb(如果需要更高并行度)
-- - 定期合并小文件:CALL sys.compact('db.my_append_table');

主键表 - 流处理作业

sql 复制代码
-- ============ 主键表流处理模板 ============

-- 1. 建表
CREATE TABLE my_pk_stream_table (
    id BIGINT,
    data STRING,
    PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'bucket' = '128',  -- 流处理并行度 = Bucket 数
    'changelog-producer' = 'input',
    'scan.mode' = 'latest'
);

-- 2. 配置
SET 'execution.runtime-mode' = 'streaming';
SET 'scan.parallelism' = '128';
SET 'scan.snapshot-time-interval' = '10s';
SET 'execution.checkpointing.interval' = '60s';
SET 'state.backend' = 'rocksdb';

-- 3. 查询
SELECT 
    COUNT(DISTINCT id) as user_cnt
FROM my_pk_stream_table;

非主键表 - 流处理作业

sql 复制代码
-- ============ 非主键表流处理模板 ============

-- 1. 建表
CREATE TABLE my_append_stream_table (
    log_id STRING,
    data STRING
) WITH (
    'bucket' = '64',  -- 可以比主键表少
    'scan.mode' = 'latest'
);

-- 2. 配置
SET 'execution.runtime-mode' = 'streaming';
SET 'scan.parallelism' = '64';
SET 'scan.snapshot-time-interval' = '10s';
SET 'execution.checkpointing.interval' = '60s';

-- 3. 查询
SELECT 
    COUNT(*) as log_cnt
FROM my_append_stream_table;

🎨 可视化速查

Split 数量对比

复制代码
场景:1 个分区,10 个 Buckets,每个 1GB

主键表(有 Level 0):
├─ Split 数量:10 个(= Bucket 数)
├─ 并行度:10
└─ 原因:Key Range 重叠,不能切分

非主键表:
├─ Split 数量:80 个(10GB / 128MB)
├─ 并行度:80
└─ 原因:可以自由切分

性能对比

复制代码
读取 100GB 数据:

主键表(需要 Merge):
[████████░░] 8 分钟

非主键表(顺序拼接):
[███░░░░░░░] 3 分钟

性能提升:2.7x

🚨 常见错误

❌ 错误 1:主键表 Bucket 太少

sql 复制代码
-- 错误配置
CREATE TABLE my_table (
    id BIGINT,
    PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'bucket' = '4'  -- ❌ 太少!批处理并行度只有 4
);

-- 正确配置
CREATE TABLE my_table (
    id BIGINT,
    PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'bucket' = '64'  -- ✅ 并行度可以达到 64
);

❌ 错误 2:非主键表 Bucket 太多

sql 复制代码
-- 低效配置
CREATE TABLE my_append_table (
    log_id STRING
) WITH (
    'bucket' = '256'  -- ❌ 太多!会产生大量小文件
);

-- 推荐配置
CREATE TABLE my_append_table (
    log_id STRING
) WITH (
    'bucket' = '16'  -- ✅ 适中,批处理并行度通过 Split 切分实现
);

❌ 错误 3:主键表使用小 Split

sql 复制代码
-- 错误配置
SET 'split.target-size' = '32mb';  -- ❌ 对主键表无效(无法切分)

-- 正确做法
-- 主键表:增加 Bucket 数量而不是减小 Split
ALTER TABLE my_pk_table SET ('bucket' = '128');

💡 优化技巧速查

主键表优化

复制代码
1. 🔧 提高并行度
   └─ 增加 Bucket 数量(核心手段)

2. 🔧 减少 Merge 开销
   └─ 定期 Compaction
   └─ 减少 Level 0 文件

3. 🔧 批处理优化
   └─ 选择 Compaction 完成后的快照
   └─ 使用 FAIR 分配模式

4. 🔧 流处理优化
   └─ Bucket 数 = 期望并行度

非主键表优化

复制代码
1. 🔧 提高并行度
   └─ 减小 split.target-size(核心手段)
   └─ 提高 scan.infer-parallelism.max

2. 🔧 减少小文件
   └─ 定期 Compaction
   └─ 适当减少 Bucket 数

3. 🔧 批处理优化
   └─ 充分利用高并行度
   └─ 使用 PREEMPTIVE 分配模式

4. 🔧 流处理优化
   └─ 考虑使用 Unaware Bucket(如果允许)

📞 决策热线

我应该用哪种表?

复制代码
问自己 3 个问题:

1. 是否需要 UPDATE 或 DELETE?
   └─ 是 → 主键表
   └─ 否 → 继续

2. 数据是否可能重复(需要去重)?
   └─ 是 → 主键表
   └─ 否 → 继续

3. 读取性能是否非常关键?
   └─ 是 → 非主键表
   └─ 否 → 都可以,推荐非主键表(性能更好)

我的配置合理吗?

复制代码
检查清单:

主键表:
☐ Bucket 数 >= 32?
☐ scan.split-assign-mode = 'fair'?
☐ 定期执行 Compaction?
☐ scan.infer-parallelism.max >= Bucket × 2?

非主键表:
☐ split.target-size <= 128mb?
☐ scan.infer-parallelism.max >= 200?
☐ Bucket 数不要太多(<= 64)?
☐ 定期合并小文件?

🔗 相关文档链接

  • 详细对比:《Paimon 主键表 vs 非主键表核心差异》
  • Split 机制:《Paimon Split 机制深度解析》
  • 配置指南:《Paimon Flink 配置实战指南》
  • 读取流程:《Paimon 分布式读取数据完整流程》

如果你喜欢这篇文章,请转发、点赞。扫描下方二维码关注我们,您会收到更多优质文章推送

在这里插入图片描述

复制代码
                           关注「Java源码进阶」,获取海量java,大数据,机器学习资料!
相关推荐
梁下轻语的秋缘3 小时前
Prompt工程核心指南:从入门到精通,让AI精准响应你的需求
大数据·人工智能·prompt
ʚB҉L҉A҉C҉K҉.҉基҉德҉^҉大3 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python
福客AI智能客服3 小时前
工单智转:电商智能客服与客服AI系统重构售后服务效率
大数据·人工智能
哈__3 小时前
多模融合 一体替代:金仓数据库 KingbaseES 重构企业级统一数据基座
数据库·重构
老邓计算机毕设3 小时前
SSM医院病人信息管理系统e7f6b(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·医院信息化·ssm 框架·病人信息管理
2601_949613023 小时前
flutter_for_openharmony家庭药箱管理app实战+药品分类实现
大数据·数据库·flutter
AIGC合规助手4 小时前
AI智能硬件I万亿市场预测+算法、大模型备案合规手册
大数据·人工智能·智能硬件
科技宅说4 小时前
聚力报告文学跨界融合 践行国际传播与地域深耕
大数据
dyyx1114 小时前
使用Scikit-learn进行机器学习模型评估
jvm·数据库·python
踢足球09295 小时前
寒假打卡:2026-01-27
数据库