搜 索

OLAP 选型指南:ClickHouse vs Doris vs Presto

  • 13阅读
  • 2023年05月13日
  • 0评论
首页 / AI/大数据 / 正文

一、前言:OLAP 选型之痛

graph TD A[老板] -->|要实时报表| B[你] C[架构师] -->|要低延迟| B D[运维] -->|要好维护| B E[财务] -->|要省钱| B B --> F["我太难了 😭"]

每个团队选 OLAP 引擎时都会纠结:

  • ClickHouse 性能强,但运维复杂
  • Doris 好维护,但性能比 ClickHouse 差一点?
  • Presto 灵活,但到底是查询引擎还是 OLAP?
  • 还有 Druid、Kylin、Impala...

本文目标:给你一个清晰的决策框架。


二、首先搞清楚:你真的需要 OLAP 吗?

2.1 数据分析技术栈全景

flowchart TB subgraph "OLTP事务型" A1[MySQL] A2[PostgreSQL] A3[Oracle] end subgraph "OLAP分析型" B1[ClickHouse] B2[Doris/StarRocks] B3[Druid] B4[Kylin] end subgraph "查询引擎" C1[Presto/Trino] C2[Spark SQL] C3[Impala] end subgraph "搜索引擎" D1[Elasticsearch] D2[OpenSearch] end subgraph "时序数据库" E1[InfluxDB] E2[TDengine] E3[TimescaleDB] end

2.2 决策树:你该选哪类技术?

flowchart TD A{数据量级?} -->|<100GB| B["MySQL/PostgreSQL
真的够用了"] A -->|100GB-10TB| C{查询模式?} A -->|>10TB| D{是否需要存储?} C -->|固定报表| E["考虑OLAP
ClickHouse/Doris"] C -->|即席查询为主| F["查询引擎
Presto/Trino"] C -->|全文检索| G["搜索引擎
Elasticsearch"] C -->|时序监控| H["时序数据库
InfluxDB/TDengine"] D -->|需要存储| I["OLAP引擎
自带存储"] D -->|已有数据湖| J["查询引擎
Presto on Hive/Iceberg"] style B fill:#90EE90 style E fill:#4ecdc4 style F fill:#ffeaa7 style G fill:#ff6b6b style H fill:#96ceb4

三、三大主角登场

3.1 定位差异

graph LR subgraph "ClickHouse" A1["定位:极致分析性能"] A2["特点:单表聚合王者"] A3["场景:日志/行为分析"] end subgraph "Doris/StarRocks" B1["定位:易用的实时数仓"] B2["特点:多表JOIN友好"] B3["场景:BI报表/实时看板"] end subgraph "Presto/Trino" C1["定位:联邦查询引擎"] C2["特点:跨数据源查询"] C3["场景:数据湖分析"] end

3.2 架构对比

graph TB subgraph "ClickHouse架构" CH1[CH Node 1] --> ZK[(ZooKeeper)] CH2[CH Node 2] --> ZK CH3[CH Node 3] --> ZK CH1 --> D1[(Local Disk)] CH2 --> D2[(Local Disk)] CH3 --> D3[(Local Disk)] end
graph TB subgraph "Doris架构" FE[FE 前端] --> BE1[BE 1] FE --> BE2[BE 2] FE --> BE3[BE 3] BE1 --> DD1[(Local Disk)] BE2 --> DD2[(Local Disk)] BE3 --> DD3[(Local Disk)] end
graph TB subgraph "Presto架构" COORD[Coordinator] --> W1[Worker 1] COORD --> W2[Worker 2] COORD --> W3[Worker 3] W1 --> S1[(Hive)] W2 --> S2[(MySQL)] W3 --> S3[(S3/HDFS)] end

3.3 一句话总结

引擎核心定位一句话特点
ClickHouseOLAP 数据库单表分析性能王者,C++ 极致优化
Doris实时数仓易用性强,MySQL 协议兼容
StarRocks实时数仓Doris 增强版,JOIN 更强
Presto/Trino查询引擎跨数据源联邦查询,无存储

四、核心维度深度对比

4.1 性能对比

xychart-beta title "典型场景性能对比(相对值,越低越快)" x-axis ["单表扫描", "单表聚合", "多表JOIN", "高并发点查", "复杂嵌套"] y-axis "响应时间" 0 --> 100 bar [10, 15, 80, 70, 60] bar [25, 25, 30, 25, 35] bar [40, 40, 25, 60, 30]
场景ClickHouseDoris/StarRocksPresto
单表扫描聚合⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
多表 JOIN⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
高并发(1000+ QPS)⭐⭐⭐⭐⭐⭐⭐⭐⭐
复杂 SQL(子查询嵌套)⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
大数据量 GROUP BY⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

4.2 SQL 兼容性

graph TB subgraph "SQL兼容度" A[ClickHouse SQL] --> A1["自有语法
学习成本高"] B[Doris/StarRocks] --> B1["MySQL兼容
无缝迁移"] C[Presto/Trino] --> C1["ANSI SQL
标准兼容"] end

具体差异示例:

-- 获取当前时间
-- ClickHouse
SELECT now();
-- Doris / Presto
SELECT CURRENT_TIMESTAMP;

-- 字符串截取
-- ClickHouse
SELECT substring('hello', 1, 3);
-- Doris
SELECT SUBSTR('hello', 1, 3);
-- Presto
SELECT SUBSTR('hello', 1, 3);

-- 日期格式化
-- ClickHouse
SELECT formatDateTime(now(), '%Y-%m-%d');
-- Doris
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d');
-- Presto
SELECT DATE_FORMAT(CURRENT_TIMESTAMP, '%Y-%m-%d');

-- 条件聚合
-- ClickHouse
SELECT sumIf(amount, status = 'PAID') FROM orders;
-- Doris / Presto
SELECT SUM(CASE WHEN status = 'PAID' THEN amount ELSE 0 END) FROM orders;

4.3 数据更新能力

flowchart LR subgraph "ClickHouse" A1["MergeTree:追加写入"] A2["ReplacingMergeTree:异步去重"] A3["CollapsingMergeTree:标记删除"] A4["实时更新能力:⭐⭐⭐"] end
flowchart LR subgraph "Doris/StarRocks" B1["Unique Key:写时合并"] B2["Primary Key:实时更新"] B3["支持标准UPDATE/DELETE"] B4["实时更新能力:⭐⭐⭐⭐⭐"] end
flowchart LR subgraph "Presto" C1["纯查询引擎"] C2["不管数据存储"] C3["更新依赖底层存储"] C4["实时更新能力:N/A"] end

4.4 运维复杂度

graph TD subgraph "ClickHouse运维" A1[部署依赖ZooKeeper] --> A2[配置复杂XML] A2 --> A3[分布式DDL手动管理] A3 --> A4[副本复制需要配置] A4 --> A5["运维复杂度:⭐⭐"] end
graph TD subgraph "Doris运维" B1[部署简单FE+BE] --> B2[自动负载均衡] B2 --> B3[元数据自动同步] B3 --> B4[副本自动管理] B4 --> B5["运维复杂度:⭐⭐⭐⭐⭐"] end
graph TD subgraph "Presto运维" C1[Coordinator+Worker] --> C2[无状态易扩展] C2 --> C3[Catalog配置] C3 --> C4[资源队列管理] C4 --> C5["运维复杂度:⭐⭐⭐⭐"] end

4.5 生态集成

graph TB subgraph "ClickHouse生态" CH[ClickHouse] --> CH1[Kafka Engine] CH --> CH2[MySQL Engine] CH --> CH3[S3 Table Function] CH --> CH4[JDBC/ODBC] CH --> CH5[Grafana] end subgraph "Doris生态" D[Doris] --> D1[Routine Load Kafka] D --> D2[Flink Connector] D --> D3[Spark Connector] D --> D4[MySQL协议] D --> D5[BI工具友好] end subgraph "Presto生态" P[Presto] --> P1[Hive Connector] P --> P2[Iceberg Connector] P --> P3[Delta Connector] P --> P4[MySQL Connector] P --> P5[Kafka Connector] P --> P6[MongoDB Connector] end

五、典型场景选型

5.1 场景一:实时日志分析

flowchart LR A[Nginx日志] --> B[Kafka] B --> C{OLAP选择} C --> D[ClickHouse ✅] subgraph "需求特点" N1["数据量大:每天10亿+"] N2["查询模式:单表聚合为主"] N3["时效性:秒级延迟"] N4["更新需求:无"] end

推荐:ClickHouse

理由:

  • 单表分析性能最强
  • 日志场景只追加不更新
  • 压缩率高,存储成本低
-- 典型查询:UV/PV统计
SELECT 
    toDate(timestamp) AS date,
    uniq(user_id) AS uv,
    count() AS pv
FROM nginx_logs
WHERE timestamp >= now() - INTERVAL 7 DAY
GROUP BY date
ORDER BY date;

5.2 场景二:BI 报表系统

flowchart LR A[业务数据库] --> B[ETL/CDC] B --> C{OLAP选择} C --> D[Doris/StarRocks ✅] subgraph "需求特点" N1["多表关联:星型/雪花模型"] N2["用户群体:业务分析师"] N3["并发要求:100+ QPS"] N4["SQL能力:标准MySQL语法"] end

推荐:Doris/StarRocks

理由:

  • MySQL 协议兼容,BI 工具无缝对接
  • 多表 JOIN 性能好
  • 高并发查询能力强
  • 运维简单,分析师也能用
-- 典型查询:销售分析报表
SELECT 
    d.region_name,
    p.category_name,
    SUM(f.sales_amount) AS total_sales,
    COUNT(DISTINCT f.customer_id) AS customer_count
FROM fact_sales f
JOIN dim_date d ON f.date_key = d.date_key
JOIN dim_product p ON f.product_key = p.product_key
WHERE d.year = 2024 AND d.quarter = 1
GROUP BY d.region_name, p.category_name
ORDER BY total_sales DESC;

5.3 场景三:数据湖即席查询

flowchart LR A[数据湖Hive/Iceberg] --> B{查询引擎选择} B --> C[Presto/Trino ✅] subgraph "需求特点" N1["数据已在数据湖中"] N2["跨多个数据源"] N3["即席探索性查询"] N4["不想数据搬迁"] end

推荐:Presto/Trino

理由:

  • 直接查询数据湖,无需数据搬迁
  • 支持跨数据源联邦查询
  • 与 Hive/Iceberg/Delta 深度集成
  • 按需扩展计算资源
-- 典型查询:跨数据源关联
SELECT 
    o.order_id,
    o.amount,
    c.name AS customer_name,
    inv.quantity AS inventory
FROM hive.sales.orders o
JOIN mysql.crm.customers c ON o.customer_id = c.id
JOIN iceberg.warehouse.inventory inv ON o.product_id = inv.product_id
WHERE o.order_date = CURRENT_DATE - INTERVAL '1' DAY;

5.4 场景四:实时数仓(需要更新)

flowchart LR A[MySQL Binlog] --> B[Flink CDC] B --> C{OLAP选择} C --> D[StarRocks Primary Key ✅] subgraph "需求特点" N1["数据需要实时更新"] N2["订单状态流转"] N3["秒级数据可见"] N4["需要DELETE操作"] end

推荐:StarRocks(Primary Key 表)或 Doris(Unique Key MOW)

理由:

  • 支持实时 UPDATE/DELETE
  • Merge-on-Write 实现秒级可见
  • 适合 CDC 实时同步场景
-- 创建Primary Key表
CREATE TABLE orders (
    order_id BIGINT,
    status VARCHAR(20),
    amount DECIMAL(10,2),
    update_time DATETIME
)
PRIMARY KEY (order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 32;

-- 实时更新(CDC数据直接写入)
UPDATE orders SET status = 'SHIPPED', update_time = NOW()
WHERE order_id = 10001;

5.5 场景五:监控指标分析(时序数据)

flowchart LR A[Prometheus/监控系统] --> B{选型} B --> C["专用时序DB ✅
InfluxDB/TDengine"] B --> D["通用OLAP
ClickHouse也可以"] subgraph "建议" N1["如果只有监控:时序DB"] N2["如果监控+业务分析:ClickHouse"] end

六、决策矩阵

6.1 综合评分

维度ClickHouseDorisStarRocksPresto
单表性能5443
多表JOIN3454
实时更新245N/A
高并发3442
SQL兼容3554
运维难度2544
数据湖集成3345
社区生态5435
成熟度5435

6.2 选型决策流程图

flowchart TD START[开始选型] --> Q1{数据是否已在数据湖?} Q1 -->|是,不想搬迁| A1[Presto/Trino] Q1 -->|否,需要独立存储| Q2{是否需要实时更新?} Q2 -->|需要频繁UPDATE/DELETE| Q3{团队运维能力?} Q2 -->|追加为主| Q4{查询模式?} Q3 -->|强| A2[StarRocks Primary Key] Q3 -->|一般| A3[Doris Unique Key MOW] Q4 -->|单表分析为主| Q5{性能要求?} Q4 -->|多表JOIN多| A4[Doris/StarRocks] Q5 -->|极致性能| A5[ClickHouse] Q5 -->|够用就行| A6[Doris] A1 --> END[选型完成] A2 --> END A3 --> END A4 --> END A5 --> END A6 --> END style A1 fill:#ffeaa7 style A2 fill:#ff6b6b style A3 fill:#4ecdc4 style A4 fill:#4ecdc4 style A5 fill:#ff6b6b style A6 fill:#4ecdc4

6.3 快速选型速查表

如果你...推荐选择理由
追求极致分析性能ClickHouse单表聚合无敌
要 MySQL 无缝迁移Doris协议完全兼容
需要频繁数据更新StarRocksPrimary Key 最成熟
已有数据湖Presto/Trino联邦查询,不搬数据
运维能力有限Doris部署运维最简单
要接各种 BI 工具Doris/StarRocks高并发 + MySQL 兼容
多数据源混合查询Presto/TrinoConnector 生态最全
预算有限Doris全开源,社区活跃

七、混合架构:不必二选一

7.1 典型混合架构

flowchart TB subgraph "数据源" S1[业务MySQL] S2[日志Kafka] S3[文件S3] end subgraph "实时层" RT[Flink CDC] end subgraph "存储层" ST1[ClickHouse
日志分析] ST2[StarRocks
实时报表] ST3[Iceberg
数据湖] end subgraph "查询层" Q1[Presto/Trino
联邦查询] end subgraph "应用层" A1[实时大屏] A2[BI报表] A3[即席查询] end S1 --> RT --> ST2 S2 --> ST1 S2 --> RT --> ST3 S3 --> ST3 ST1 --> A1 ST2 --> A1 & A2 ST3 --> Q1 --> A3

7.2 场景分工

数据类型推荐存储查询方式
实时交易数据StarRocks直接查询
日志/行为数据ClickHouse直接查询
历史归档数据Iceberg on S3Presto 查询
跨源关联分析-Presto 联邦查询

八、Presto/Trino 专题补充

8.1 Presto vs Trino

timeline title Presto/Trino 发展史 2012 : Facebook 创建 Presto 2013 : Presto 开源 2019 : 核心团队离开FB创立Starburst 2020 : 更名为Trino(社区版) 2021 : PrestoDB vs Trino 分道扬镳
项目PrestoDBTrino
维护方Facebook (Meta)独立社区 + Starburst
开源协议Apache 2.0Apache 2.0
社区活跃度中等更活跃
商业支持Ahana (已被Starburst收购)Starburst
建议选择都可以,Trino 略推荐

8.2 Presto/Trino 核心优势

mindmap root((Presto/Trino)) 联邦查询 跨数据源JOIN 无需ETL 数据不搬迁 Connector生态 50+ 数据源 Hive/Iceberg/Delta MySQL/PostgreSQL Kafka/Redis 内存计算 全内存Pipeline 低延迟 大数据量交互式 标准SQL ANSI SQL兼容 学习成本低

8.3 Presto/Trino 典型使用场景

-- 场景1:直接查询Iceberg数据湖
SELECT 
    date_trunc('day', event_time) AS date,
    count(*) AS events
FROM iceberg.events.user_activity
WHERE event_time >= TIMESTAMP '2024-01-01'
GROUP BY 1;

-- 场景2:联邦查询
SELECT 
    m.order_id,
    m.amount,
    h.user_name,
    h.user_level
FROM mysql.ecommerce.orders m
JOIN hive.warehouse.users h ON m.user_id = h.user_id
WHERE m.order_date = CURRENT_DATE;

-- 场景3:数据湖时间旅行
SELECT * FROM iceberg.warehouse.orders 
FOR VERSION AS OF 123456789;  -- 查询历史版本

8.4 什么时候不该用 Presto?

graph TD A[不适合Presto的场景] --> B[需要高并发短查询] A --> C[需要实时数据更新] A --> D[需要超低延迟<100ms] A --> E[简单的单数据源场景] B --> B1["Presto资源开销大
不适合高QPS"] C --> C1["Presto是查询引擎
不管数据存储"] D --> D1["内存Pipeline有开销
毫秒级做不到"] E --> E1["杀鸡用牛刀
直接用原生数据库"]

九、成本对比

9.1 TCO (总体拥有成本) 构成

pie title OLAP 成本构成 "服务器硬件" : 40 "存储成本" : 25 "人力运维" : 20 "软件License" : 10 "培训学习" : 5

9.2 各引擎成本对比

成本项ClickHouseDorisStarRocksPresto
软件费用免费免费免费/企业版收费免费/Starburst收费
硬件需求高(内存密集)中(无存储)
存储成本低(压缩率高)依赖底层存储
运维人力
学习成本

9.3 硬件配置建议

引擎最小配置(PoC)生产配置
ClickHouse3节点 x 16C64G6+节点 x 32C128G
Doris3FE+3BE x 16C64G3FE+6BE x 32C128G
StarRocks3FE+3BE x 16C64G3FE+6BE x 32C128G
Presto1Coord+3Worker x 16C64G2Coord+10Worker x 32C128G

十、迁移指南

10.1 从 Hive 迁移

flowchart LR A[Hive] --> B{目标} B -->|加速固定报表| C[Doris/StarRocks] B -->|保留数据湖+加速| D[Presto on Hive] B -->|日志分析场景| E[ClickHouse] C --> C1["方案:Spark ETL 同步
或 Hive Catalog 直读"] D --> D1["方案:直接配置 Hive Connector"] E --> E1["方案:ClickHouse Hive Engine
或 ETL 同步"]

10.2 从 MySQL 迁移

flowchart LR A[MySQL] --> B{实时性需求} B -->|T+1离线| C["DataX/Sqoop
批量同步"] B -->|实时同步| D["Flink CDC
增量同步"] C --> E[Doris/StarRocks] D --> E subgraph "优势" E --> F["MySQL协议兼容
SQL几乎不用改"] end

10.3 SQL 迁移注意事项

-- MySQL → Doris:大部分SQL直接可用
-- 注意事项:

-- 1. 自增ID:Doris不支持AUTO_INCREMENT
-- MySQL
CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY);
-- Doris
CREATE TABLE t (id BIGINT) 
DISTRIBUTED BY HASH(id) BUCKETS 10;
-- 需要业务层生成ID

-- 2. 索引:Doris使用不同的索引策略
-- MySQL
CREATE INDEX idx_name ON t(name);
-- Doris:通过排序键和Bloom Filter实现

-- 3. 事务:Doris不支持传统事务
-- 需要在应用层处理一致性

十一、总结

11.1 一张图总结

quadrantChart title "OLAP 引擎定位" x-axis "运维简单" --> "运维复杂" y-axis "多表JOIN弱" --> "多表JOIN强" quadrant-1 "全能型" quadrant-2 "JOIN专家" quadrant-3 "易用型" quadrant-4 "性能极客" "ClickHouse": [0.8, 0.3] "Doris": [0.2, 0.6] "StarRocks": [0.4, 0.8] "Presto": [0.5, 0.7]

11.2 最终建议

graph TD A["你的最佳选择"] --> B{核心诉求是什么?} B -->|"极致单表性能
日志/行为分析"| C["ClickHouse"] B -->|"运维简单
MySQL生态迁移"| D["Apache Doris"] B -->|"实时更新
复杂JOIN"| E["StarRocks"] B -->|"已有数据湖
跨源查询"| F["Presto/Trino"] C --> C1["适合:日志分析、行为分析、实时监控"] D --> D1["适合:BI报表、实时看板、中小团队"] E --> E1["适合:实时数仓、复杂分析、大型企业"] F --> F1["适合:数据湖查询、联邦分析、探索性分析"] style C fill:#ff6b6b style D fill:#4ecdc4 style E fill:#ffeaa7 style F fill:#96ceb4

记住这个口诀:

日志分析选 ClickHouse,性能极致没得说

BI 报表选 Doris,MySQL 兼容易上手

实时更新选 StarRocks,Primary Key 真给力

数据湖用 Presto,联邦查询不搬迁


十二、附录:常见 FAQ

Q1: ClickHouse 和 Doris 能不能一起用?
A: 可以。ClickHouse 处理日志分析,Doris 处理 BI 报表,各取所长。

Q2: Presto 性能不如 ClickHouse,为什么还要用?
A: Presto 的价值在于联邦查询和数据湖集成,不是为了替代 ClickHouse。

Q3: StarRocks 和 Doris 怎么选?
A: 预算够选 StarRocks(有商业支持),追求稳定选 Doris(Apache 背书)。

Q4: 小团队没有专职 DBA,选哪个?
A: 强烈推荐 Doris,部署运维最简单,社区文档也多。

Q5: 数据量不大(<1TB),有必要上 OLAP 吗?
A: 没必要。MySQL 8.0 + 合理的索引就够用了,别为了技术而技术。

评论区
暂无评论
avatar