表的类型

 

```
开始
  ↓
需要保留所有明细数据?
  ├─ 是 → Duplicate Key 表
  └─ 否 → 需要聚合(SUM/MAX/REPLACE)?
           ├─ 是 → Aggregate Key 表(写时聚合,查询快)
           └─ 否 → 需要 Key 唯一性?
                    ├─ 是 → 查询频率 >> 写入频率?
                    │        ├─ 是 → Primary Key 表(MOW,查询最快)
                    │        └─ 否 → Unique Key 表
                    │                 ├─ MOR(写入频繁)
                    │                 └─ MOW(查询频繁)
                    └─ 否 → Duplicate Key 表
```


 


 


 
表类型	         聚合时机	实际情况
Aggregate Key	写时聚合	✅ 正确
Unique Key	    读时或写时(可选)	⚠️ 默认 MOR(读时合并),可配置 MOW(写时去重)
Primary Key	   写时去重	✅ 只支持 MOW,性能最优

核心机制

 
MOR (Merge-On-Read) - 读时合并

写入时:不做处理,直接追加(写入快)
查询时:合并多版本数据(查询慢)
适合: 高频写入、低频查询场景
MOW (Merge-On-Write) - 写时合并

写入时:判断并删除旧数据(写入慢)
查询时:直接读取最新数据(查询快)
适合: 低频写入、高频查询场景

性能对比(数据量大时)

 
场景	 最优选择
高频写入 + 低频查询	  Unique Key (MOR) 写入最快
低频写入 + 高频查询	  Aggregate Key / Primary Key 查询最快
频繁更新 + 高频查询	  Primary Key 综合性能最优

报表统计分析	     Aggregate Key 预聚合,存储最小


关键结论

 
✅ Primary Key 表性能最优(不是读时聚合,而是写时去重)

查询最快(主键索引优化)
支持删除操作
适合核心业务表

 


 
#### 查询性能对比

-  表类型 | 写入性能 | 查询性能 | 存储空间 | 数据量:1000 万行 | 数据量:1 亿行 |
- --------|---------|---------|---------|-----------------|----------------|
- **Duplicate Key** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | 10 GB | 10 GB | 100 GB |
- **Aggregate Key** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 1 GB | 1 GB | 10 GB |
- **Unique Key (MOR)** | ⭐⭐⭐⭐⭐ | ⭐⭐ | 8 GB(多版本) | 8 GB | 80 GB |
- **Unique Key (MOW)** | ⭐⭐⭐ | ⭐⭐⭐⭐ | 2 GB | 2 GB | 20 GB |
- **Primary Key (MOW)** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 2 GB | 2 GB | 20 GB |

**结论:**
- **Aggregate Key**:查询最快(已预聚合),存储最小
- **Primary Key**:查询最快(主键索引优化),适合高频查询
- **Unique Key (MOR)**:写入最快,查询慢,适合高频写入场景

 

#### 场景性能测试

**场景 1:高频写入,低频查询**

- 操作 | Duplicate Key | Aggregate Key | Unique Key (MOR) | Primary Key |
- 写入 100 万条 | 10 秒 | 15 秒 | 8 秒 ✅ | 12 秒 |
- 查询 1 次 | 0.5 秒 | 0.1 秒 | 1.5 秒 | 0.1 秒 |

**推荐:** Unique Key (MOR) - 写入最快

---

**场景 2:低频写入,高频查询(报表分析)**

- 操作 | Duplicate Key | Aggregate Key | Unique Key (MOR) | Primary Key |
- 写入 100 万条 | 10 秒 | 15 秒 | 8 秒 | 12 秒 |
- 查询 1000 次 | 500 秒 | 100 秒 ✅ | 1500 秒 | 100 秒 ✅ |

**推荐:** Aggregate Key 或 Primary Key - 查询最快

---

**场景 3:频繁更新,高频查询**

- 操作 | Duplicate Key | Aggregate Key | Unique Key (MOR) | Unique Key (MOW) | Primary Key |
- 更新 10 万条 | 5 秒 | 8 秒 | 2 秒 ✅ | 6 秒 | 5 秒 |
- 查询 1000 次 | 500 秒 | 100 秒 ✅ | 1500 秒 | 120 秒 | 100 秒 ✅ |

**推荐:** Primary Key - 综合性能最优

 


 


 


 


 


 


分桶键
在 Doris 中创建表时,**分桶键并不是必须指定的**。这取决于你所选择的分桶方式: * **✅ 使用 Random 分桶**:**不需要指定分桶键**。数据会随机、均匀地分布到各个分桶中,可以有效避免数据倾斜。 * **🔑 使用 Hash 分桶**:**必须指定分桶键**。你需要选择一列或多列作为分桶键,Doris会根据这些列的Hash值将数据分配到不同的分桶中。 > **提醒**:Random 分桶仅适用于 `DUPLICATE KEY`(明细模型)表,`UNIQUE`(主键/唯一模型)和 `AGGREGATE`(聚合模型)表**不能**使用 Random 分桶。 ### 📝 两种分桶方式对比 **Hash 分桶** (`DISTRIBUTED BY HASH(...)`) * **分桶键**:**必须指定** * **适用表模型**:DUPLICATE、UNIQUE、AGGREGATE * **适用场景**:有频繁作为过滤条件的高基数列(如 `user_id`),或需要进行高并发点查。 **Random 分桶** (`DISTRIBUTED BY RANDOM`) * **分桶键**:**不需要指定** * **适用表模型**:仅 `DUPLICATE KEY`(明细模型) * **适用场景**:没有固定的过滤条件,或分桶键列数据分布不均,担心手动选错列导致数据倾斜。 ### 💎 选择建议 总的来说,如果业务场景明确,有高频使用的过滤字段(如用户ID、订单ID),选择 **Hash 分桶**并正确指定分桶键,可以获得最佳的查询性能。 如果数据导入频繁且对数据均匀分布的要求高于特定列的查询剪裁,那么对于明细模型表来说,**Random 分桶**是一个简单且有效的选择。

 


 


 


 


参考