Article

数据存储 Doris

更新于:2026-07-12

第一章:Doris 概述与核心架构

1.1 什么是 Apache Doris

概念名称说明注意事项
Apache Doris一个高性能、实时的 MPP(大规模并行处理)分析型数据库,原名 Palo,由百度研发,后捐赠给 Apache 基金会。支持高并发低延迟的即席查询。Doris 不是关系型数据库(OLTP),而是面向 OLAP 场景设计,适用于实时数据分析。
开源状态Apache 顶级项目,采用 Apache 2.0 许可证,社区活跃,支持多云部署。需关注版本稳定性,生产环境建议使用稳定版本(如 1.2.x、2.0.x)。
架构特点纯 C++ 编写,无外部依赖(除可选 Broker),部署简单,兼容 MySQL 协议。虽无强依赖,但与 Hive、Kafka 等集成时需部署 Broker 组件。

1.2 Doris 的核心特性与适用场景

特性名称说明注意事项
实时数据分析支持高并发、低延迟的实时数据导入与查询,数据秒级可见。导入频率过高可能影响查询性能,需合理控制导入节奏。
MPP 架构查询时多节点并行执行,充分利用集群资源,提升查询效率。查询性能受 BE 节点数量和资源配置影响较大。
向量化引擎自 0.15 版本起引入向量化执行引擎,显著提升计算性能。需使用支持向量化的版本(推荐 1.0+),旧版本性能较低。
兼容 MySQL 协议支持使用 MySQL 客户端或 JDBC 连接,降低接入成本。仅兼容部分 MySQL 语法,不支持事务、存储过程等 OLTP 功能。
高可用FE 支持多副本(Leader/Follower),BE 支持副本间数据冗余。至少需要 3 个 FE 节点实现高可用(奇数个),否则无法选举 Leader。
适用场景实时数仓、报表系统、用户行为分析、日志分析等。不适用于高频更新、强事务一致性要求的场景。

1.3 Doris 架构组件详解(FE、BE、Broker)

组件名称说明注意事项
FE(Frontend)负责元数据管理、查询解析、计划生成与调度。分为 Leader、Follower、Observer 三种角色。Leader 节点处理写操作和元数据变更;Follower 参与选举;Observer 用于扩展读能力。
BE(Backend)负责数据存储、查询执行和数据导入。每个 BE 存储部分分片(Tablet),支持水平扩展。BE 节点宕机不影响元数据,但可能导致查询失败或降级。
Broker可选组件,用于访问外部存储(如 HDFS、S3、BOS)进行数据导入或导出。使用 Broker Load 时必须部署 Broker;Stream Load 可不依赖 Broker。
元数据同步FE 之间通过 BDBJE 同步元数据,保证一致性。避免手动修改元数据目录,可能导致集群异常。
查询流程客户端 → FE(解析 SQL,生成计划) → BE(执行任务,返回结果) → FE(合并结果) → 客户端网络延迟或 BE 负载过高可能导致查询变慢。

1.4 数据模型概览(Aggregate、Unique、Duplicate)

数据模型说明注意事项
Aggregate 模型相同主键的数据在导入时自动聚合(如 SUM、REPLACE)。适合指标类数据统计。需在建表时指定聚合函数(如 SUM、MAX、MIN),非主键列必须声明聚合方式。
Unique 模型主键唯一,新数据会覆盖旧数据,实现”更新”语义。类似传统数据库的主键更新。从 1.0 版本起支持全局一致性更新;需开启 enable_unique_key_merge_on_write 提升查询性能。
Duplicate 模型不做任何聚合或去重,原始数据全部保留。适合日志、明细数据存储。适合高频写入、无需聚合的场景,但存储开销较大。
模型选择建议根据业务需求选择:指标汇总 → Aggregate;主键更新 → Unique;明细存储 → Duplicate建表后无法更改数据模型,需提前规划。

第二章:环境准备与快速入门

2.1 系统要求与环境依赖

项目要求注意事项
操作系统Linux(CentOS 7+/Ubuntu 16.04+)推荐使用 CentOS 7 或更高版本,避免使用过旧内核。
CPU建议 8 核以上FE 可用较少资源,BE 建议高配以支持并行计算。
内存FE:8GB+,BE:16GB+(根据数据量调整)内存不足可能导致查询失败或导入超时。
磁盘建议使用 SSD,预留足够空间(数据量 × 副本数 × 2)BE 节点需配置 storage_root_path 指定数据目录。
网络千兆以上局域网,低延迟集群节点间网络不稳定会影响导入和查询性能。
Java 环境FE 需要 JDK 1.8BE 无需 Java;确保 JAVA_HOME 环境变量正确设置。
GCC 版本若从源码编译,需 GCC 5.3+官方提供编译好的二进制包,通常无需自行编译。

2.2 单机部署与集群部署指南

部署类型说明注意事项
单机部署所有组件(FE、BE)运行在同一台机器,适用于测试和学习。不具备高可用性,生产环境禁用。
集群部署FE 和 BE 分布在多台机器,FE 至少 1 个(推荐 3 个高可用),BE 至少 1 个。FE 节点数建议为奇数(1、3、5),便于选举 Leader。
部署步骤概览解压 Doris 包 → 配置 fe/conf/fe.conf 和 be/conf/be.conf → 启动 FE,再启动 BE → 通过 MySQL 客户端连接首次启动前需确保端口未被占用(FE 默认 9010,BE 默认 9060)。
配置文件位置FE:fe/conf/;BE:be/conf/修改配置后需重启服务生效。
典型配置项priority_networks:指定绑定 IP;meta_dir:FE 元数据路径;storage_root_path:BE 数据路径多网卡环境必须设置 priority_networks,否则可能绑定错误 IP。

2.3 服务启动与状态检查

操作命令用途注意事项
启动 FEsh bin/start_fe.sh --daemon启动前端服务首次启动前需执行 mysql -uroot < fe/sql/create_db.sql 初始化元数据库。
停止 FEsh bin/stop_fe.sh --daemon停止前端服务建议正常关闭,避免强制 kill 导致元数据损坏。
启动 BEsh bin/start_be.sh --daemon启动后端服务必须先启动 FE 并添加 BE 节点(通过 SQL)。
停止 BEsh bin/stop_be.sh --daemon停止后端服务强制停止可能导致正在进行的导入任务失败。
检查 FE 状态http://<fe_host>:8030/api/bootstrap 或查看 fe/log/fe.log确认 FE 是否正常启动日志中出现 finished to load meta data 表示启动成功。
检查 BE 状态查看 be/log/be.INFO确认 BE 是否注册到 FE日志中出现 master has accepted this backend 表示注册成功。

2.4 使用 MySQL 客户端连接 Doris

项目说明注意事项
连接命令mysql -h <fe_host> -P 9030 -u root -p默认端口 9030,用户 root 无密码
客户端工具支持标准 MySQL 客户端、Navicat、DBeaver、JDBC 等仅支持 MySQL 5.7 基础语法,不支持存储过程、视图等高级特性。
默认用户root(管理员),无密码首次登录后建议使用 SET PASSWORD = PASSWORD('xxx'); 设置密码。
连接失败常见原因FE 未启动;防火墙阻止 9030 端口;priority_networks 配置错误检查 FE 日志和网络连通性。
查看集群状态SHOW PROC '/frontends'; 查看 FE 节点状态;SHOW PROC '/backends'; 查看 BE 节点状态

2.5 快速创建数据库与表并插入数据

操作语法用途代码示例注意事项
创建数据库CREATE DATABASE [IF NOT EXISTS] db_name;创建新的数据库CREATE DATABASE example_db;数据库名需唯一,避免使用保留字。
使用数据库USE db_name;切换当前操作数据库USE example_db;必须先选择数据库才能建表。
创建表CREATE TABLE [IF NOT EXISTS] table_name (...)定义表结构与数据模型见下方示例必须指定分桶列和桶数;主键模型需用 UNIQUE KEY 显式声明。
插入数据INSERT INTO table_name VALUES (...);单条或批量插入数据INSERT INTO example_tbl VALUES (1001, 'Alice', 25, 8000.00);大量数据插入建议使用 Stream Load 或 Broker Load。
查询数据SELECT * FROM table_name;查看表中数据SELECT * FROM example_tbl;支持标准 SQL 查询语法。
查看表结构DESCRIBE table_name;DESC table_name;显示表字段信息DESC example_tbl;可验证建表是否成功。

创建表示例:

CREATE TABLE example_tbl (
    user_id BIGINT,
    name VARCHAR(50),
    age INT,
    salary DECIMAL(10,2)
)
DISTRIBUTED BY HASH(user_id) BUCKETS 10;

第三章:数据定义语言(DDL)

3.1 数据库操作(CREATE、DROP、ALTER DATABASE)

操作语法用途代码示例注意事项
创建数据库CREATE DATABASE [IF NOT EXISTS] db_name [PROPERTIES ("key" = "value")];创建新数据库,可设置属性如副本数CREATE DATABASE test_db;
CREATE DATABASE test_db PROPERTIES ("replication_num" = "3");
若不指定 replication_num,默认为 1(单副本),生产环境建议设为 3。
删除数据库DROP DATABASE [IF EXISTS] db_name;永久删除数据库及其所有表DROP DATABASE test_db;删除操作不可逆,所有数据将被清除,请谨慎操作。
修改数据库属性ALTER DATABASE db_name SET PROPERTIES ("key" = "value");修改数据库级属性,如副本数ALTER DATABASE test_db SET PROPERTIES ("replication_num" = "3");仅支持修改 replication_num 等有限属性;修改后对后续建表生效,不影响已有表。
查看数据库SHOW DATABASES;SHOW CREATE DATABASE db_name;列出所有数据库或查看建库语句SHOW DATABASES;
SHOW CREATE DATABASE example_db;
SHOW CREATE DATABASE 可用于导出建库语句。

3.2 表的创建:CREATE TABLE 详解

子句/选项语法用途代码示例注意事项
基本建表CREATE TABLE [IF NOT EXISTS] [database.]table_name (...)定义表结构CREATE TABLE tbl1 (id INT, name VARCHAR(20));必须在 USE db; 或指定数据库名。
声明数据模型AGGREGATE KEY (col1, ...) / UNIQUE KEY (col1, ...) / DUPLICATE KEY (col1, ...)指定数据模型类型UNIQUE KEY(user_id) ...必须显式声明 KEY 类型;默认为 DUPLICATE KEY。
分桶设置DISTRIBUTED BY HASH(key) BUCKETS N设置分桶列和桶数DISTRIBUTED BY HASH(user_id) BUCKETS 10;推荐桶数为 BE 数量的 1~10 倍;避免数据倾斜。
分区设置PARTITION BY RANGE (col) (...)按范围分区,支持自动/手动分区见下方示例分区列必须是前缀列;建议按时间分区便于管理。
自动分区PARTITION BY RANGE (col) () DISTRIBUTED ... PROPERTIES("dynamic_partition.enable" = "true", ...)动态创建未来分区见下方示例需在 FE 配置中启用动态分区功能。
属性设置PROPERTIES ("key" = "value", ...)设置表级属性,如副本数、压缩等PROPERTIES ("replication_num" = "3", "bloom_filter_columns" = "name", "in_memory" = "false");replication_num 建议设为 3;bloom_filter 仅支持 KV 列。

分区设置示例:

PARTITION BY RANGE(time_date) (
    PARTITION p202501 VALUES LESS THAN ("2025-02-01"),
    PARTITION p202502 VALUES LESS THAN ("2025-03-01")
)

自动分区示例:

PROPERTIES (
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-3",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p"
);

3.3 表结构修改:ALTER TABLE 常用操作

操作类型语法用途代码示例注意事项
添加列ALTER TABLE table_name ADD COLUMN col_name type [KEY] [DEFAULT value] [AFTER existing_col];在指定位置添加新列ALTER TABLE tbl1 ADD COLUMN age INT DEFAULT '0' AFTER name;非主键列可添加;主键模型中 ADD COLUMN 有约束。
删除列ALTER TABLE table_name DROP COLUMN col_name;删除指定列ALTER TABLE tbl1 DROP COLUMN age;不支持删除主键列或分桶列;删除后数据不可恢复。
修改列类型ALTER TABLE table_name MODIFY COLUMN col_name new_type;更改列的数据类型ALTER TABLE tbl1 MODIFY COLUMN name VARCHAR(50);仅支持扩大类型(如 INT → BIGINT),不支持缩小或改变语义。
重命名列ALTER TABLE table_name CHANGE COLUMN old_name new_name new_type;修改列名和类型ALTER TABLE tbl1 CHANGE COLUMN name user_name VARCHAR(50);必须重新指定类型,即使不变。
添加分区ALTER TABLE table_name ADD PARTITION partition_name VALUES LESS THAN ("value");手动添加新分区ALTER TABLE tbl1 ADD PARTITION p202503 VALUES LESS THAN ("2025-04-01");分区值必须大于当前最大分区。
删除分区ALTER TABLE table_name DROP PARTITION partition_name;删除指定分区ALTER TABLE tbl1 DROP PARTITION p202501;删除后该分区数据永久丢失。
暂停/恢复作业ALTER TABLE table_name [CANCEL] SCHEMA CHANGE;取消正在进行的 schema 变更ALTER TABLE tbl1 CANCEL SCHEMA CHANGE;schema change 是异步操作,可通过 SHOW ALTER TABLE 查看状态。

3.4 表与数据库的删除:DROP TABLE / DATABASE

操作语法用途代码示例注意事项
删除表DROP TABLE [IF EXISTS] [database.]table_name [FORCE];删除指定表DROP TABLE tbl1;普通删除进入回收站,可恢复;加 FORCE 则永久删除。
强制删除表DROP TABLE table_name FORCE;绕过回收站,永久删除DROP TABLE tbl1 FORCE;无法恢复,请谨慎使用。
恢复表RECOVER TABLE [database.]table_name;从回收站恢复已删除表RECOVER TABLE tbl1;仅适用于未加 FORCE 的删除操作。
查看回收站SHOW RECYCLEBIN;显示被删除但可恢复的对象SHOW RECYCLEBIN;可查看 TableName、OriginName、DropTime 等信息。
清空回收站ADMIN EMPTY TRASH;手动清理回收站中过期数据ADMIN EMPTY TRASH;回收站默认 1 天自动清理,也可手动触发。
删除数据库DROP DATABASE db_name;删除数据库及所有表DROP DATABASE test_db;与 DROP TABLE 类似,也支持回收站机制。

3.5 分区(Partition)与分桶(Bucket)策略配置

概念说明注意事项
分区(Partition)将大表按某一列(通常是时间)划分为多个逻辑部分,提升查询效率和管理便利性支持 RANGE 和 LIST 分区;分区列必须是前缀列;建议按时间分区。
分桶(Bucket)在每个分区内,按哈希值将数据进一步分散到多个桶中,实现数据均衡和并行处理分桶列建议选择高基数列(如 ID);桶数应为 BE 数量的整数倍,避免倾斜。
分区裁剪查询时自动跳过不相关的分区,显著提升性能WHERE 条件中需包含分区列才能触发裁剪。
分桶剪枝查询时仅扫描相关桶,减少 I/O依赖分桶列在查询条件中出现。
动态分区自动按时间单位(DAY/WEEK/MONTH)创建未来分区需在表属性中启用并配置 dynamic_partition.* 参数;适合日志类表。
多级分区支持先 RANGE 再 HASH 的复合分区方式语法:PARTITION BY RANGE(...) ( ... ) DISTRIBUTED BY HASH(...) BUCKETS N;

第四章:数据操作语言(DML)

4.1 数据导入:LOAD、BROKER LOAD、STREAM LOAD、ROUTINE LOAD

导入方式语法/方式用途代码示例注意事项
STREAM LOADHTTP PUT 请求或 curl 命令实时导入本地或 HTTP 数据,同步返回结果curl --location-trusted -u user:passwd -T data.csv http://fe_host:8030/api/db1/tbl1/_stream_load支持 CSV、JSON、Parquet 等格式;适合中小批量实时导入。
BROKER LOADLOAD LABEL db.label (DATA INFILE (...) INTO TABLE ...)从 HDFS/S3/BOS 等外部存储异步导入大数据见下方示例需部署 Broker;适合离线批量导入;支持事务性。
ROUTINE LOADCREATE ROUTINE LOAD ... FROM KAFKA ...从 Kafka 持续订阅数据,实现流式导入见下方示例支持 Exactly-Once 语义;需监控消费延迟。
INSERT INTOINSERT INTO table VALUES (...)INSERT INTO SELECT ...单条或批量插入,或从其他表导入INSERT INTO tbl1 VALUES (1, 'a');
INSERT INTO tbl2 SELECT * FROM tbl1;
大量数据插入性能较差,建议用于测试或小数据量。
MySQL LoadLOAD DATA LOCAL INFILE ...通过 MySQL 协议导入本地文件LOAD DATA LOCAL INFILE 'data.csv' INTO TABLE tbl1;实际走的是 Stream Load 协议,需客户端支持。

BROKER LOAD 示例:

LOAD LABEL example_db.label1 (
    DATA INFILE("hdfs://path/*.csv")
    INTO TABLE tbl1
    COLUMNS TERMINATED BY ","
);

ROUTINE LOAD 示例:

CREATE ROUTINE LOAD example_db.job1 ON tbl1
PROPERTIES("desired_concurrent_number"="1")
FROM KAFKA (
    "kafka_broker_list" = "kafka:9092",
    "kafka_topic" = "doris"
);

4.2 数据查询:SELECT 基础语法

子句语法用途代码示例注意事项
基本查询SELECT col1, col2 FROM table;选择指定列SELECT id, name FROM tbl1;使用 * 可能影响性能,建议明确列名。
条件过滤SELECT ... WHERE condition;按条件筛选数据SELECT * FROM tbl1 WHERE age > 20;尽量使用索引列(前缀列、Bloom Filter 列)提升性能。
去重查询SELECT DISTINCT col FROM table;返回唯一值SELECT DISTINCT name FROM tbl1;大数据量去重消耗内存,可能触发 spill。
限制返回SELECT ... LIMIT N;限制结果行数SELECT * FROM tbl1 LIMIT 10;常用于调试或分页查询(配合 ORDER BY)。
排序查询SELECT ... ORDER BY col [ASC|DESC];按列排序SELECT * FROM tbl1 ORDER BY age DESC;排序为全局操作,大数据量可能较慢。
别名使用SELECT col AS alias FROM table;为列或表设置别名SELECT name AS user_name FROM tbl1 t;提高 SQL 可读性。
表达式计算SELECT col1 + col2 FROM table;支持算术、逻辑、函数表达式SELECT salary * 1.1 FROM tbl1;Doris 内置丰富函数(数学、字符串、日期等)。

4.3 数据更新与删除:UPDATE、DELETE(基于 Unique 模型)

操作语法用途代码示例注意事项
删除数据DELETE FROM table WHERE condition;根据条件删除行(仅 Unique 模型)DELETE FROM tbl1 WHERE id = 1001;必须包含主键列在 WHERE 中;不支持非主键条件删除。
更新数据UPDATE table SET col = value WHERE key = val;更新指定行的列值UPDATE tbl1 SET name = 'Bob' WHERE id = 1001;仅 2.0+ 版本支持 UPDATE 语句;仍需基于主键。
删除限制支持 AND 多条件,但必须包含所有主键列DELETE FROM tbl1 WHERE id = 1 AND name = 'a';不支持 OR、IN、LIKE 等复杂条件。
异步执行删除操作异步执行,立即返回任务 ID返回 {"label":"delete_123", "status":"PENDING"}可通过 SHOW DELETE FROM table_name; 查看状态。
性能影响大量删除可能导致查询性能下降删除后建议执行 COMPACT 合并数据版本。

4.4 批量插入:INSERT INTO … VALUES / SELECT

操作语法用途代码示例注意事项
批量 VALUESINSERT INTO table VALUES (...), (...), ...;一次插入多行数据INSERT INTO tbl1 VALUES (1,'a'),(2,'b');行数不宜过多(建议 < 1000),否则可能超时。
插入 SELECTINSERT INTO table SELECT ... FROM other_table;从其他表导入数据INSERT INTO tbl2 SELECT * FROM tbl1;适合表间迁移或 ETL 场景。
异步插入INSERT INTO ... SELECT ... 默认同步同步执行,等待完成大数据量插入建议使用 Broker Load 或 Stream Load。
插入分区表自动写入对应分区按分区列值自动路由INSERT INTO partitioned_tbl VALUES ('2025-01-01', 100);确保数据符合分区范围,否则报错。
错误处理可通过 SET enable_insert_strict = false; 忽略错误行容忍部分数据错误SET enable_insert_strict = false; INSERT INTO ...开启后仅记录错误日志,部分数据可能丢失。

4.5 导入作业管理与状态查询

操作语法用途代码示例注意事项
查看导入作业SHOW LOAD [FROM db] [WHERE label = "xxx"];查看所有或指定导入任务状态SHOW LOAD FROM example_db;显示状态(FINISHED、CANCELLED)、进度、错误信息等。
查看 Broker LoadSHOW LOAD WHERE label = "label1";查看异步导入状态SHOW LOAD WHERE label = "job1";支持分页查询,LIMIT 控制返回数量。
查看 Stream Load通过返回的 Label 在 SHOW LOAD 中查询Stream Load 也生成 labelSHOW LOAD WHERE label = "stream_load_1";即使同步返回成功,也可查详情。
查看 Routine LoadSHOW ROUTINE LOAD [FROM db] [FOR job_name];查看流式导入状态SHOW ROUTINE LOAD FOR job1;可查看消费位点、速度、错误日志。
取消导入作业CANCEL LOAD FROM db WHERE label = "xxx";终止正在运行的导入任务CANCEL LOAD FROM example_db WHERE label = "job1";仅对未完成任务有效。
查看错误行SHOW LOAD WARNINGS FROM db WHERE label = "xxx";查看导入失败的具体数据行SHOW LOAD WARNINGS FROM example_db WHERE label = "job1";需在导入时启用 max_filter_ratio > 0 才能捕获。

第五章:数据查询语言(DQL)深入

5.1 SELECT 子句与列选择

语法项语法格式用途代码示例注意事项
选择所有列SELECT * FROM table;查询表中所有字段SELECT * FROM employee;不推荐用于生产,影响性能且不明确字段。
选择指定列SELECT col1, col2 FROM table;仅返回需要的列SELECT name, age FROM employee;减少 I/O 和网络传输,提升查询效率。
列别名SELECT col AS alias FROM table;为列设置别名便于引用或展示SELECT salary AS sal, name AS full_name FROM employee;别名可用于 ORDER BY 或外部查询引用。
表达式列SELECT col1 + col2 FROM table;返回计算结果SELECT id, salary * 1.1 AS new_salary FROM employee;支持算术、字符串拼接、函数调用等表达式。
常量列SELECT col, 'fixed' FROM table;添加固定值列SELECT name, 'CN' AS country FROM employee;适用于补全维度信息。
去重列值SELECT DISTINCT col FROM table;返回唯一值SELECT DISTINCT dept FROM employee;大数据量时消耗内存高,可能触发磁盘排序(spill)。

5.2 WHERE 条件过滤与表达式

条件类型语法格式用途代码示例注意事项
比较操作=, !=, <, >, <=, >=基本比较SELECT * FROM emp WHERE age >= 30;推荐在分区列、分桶列上使用以触发剪枝。
范围查询BETWEEN ... AND ...匹配区间值SELECT * FROM emp WHERE age BETWEEN 20 AND 30;等价于 col >= val1 AND col <= val2
枚举匹配IN (val1, val2, ...)匹配多个离散值SELECT * FROM emp WHERE dept IN ('HR', 'IT');IN 列表过大(>1000)可能影响性能。
模式匹配LIKE 'pattern'模糊匹配(支持 %_SELECT * FROM emp WHERE name LIKE 'A%';不区分大小写;前缀匹配性能较好,后缀匹配较差。
正则匹配REGEXP 'pattern'RLIKE使用正则表达式过滤SELECT * FROM emp WHERE name REGEXP '^A.*';性能低于 LIKE,仅用于复杂模式。
空值判断IS NULL, IS NOT NULL判断是否为空SELECT * FROM emp WHERE phone IS NULL;不能用 = NULL 判断空值。
逻辑组合AND, OR, NOT组合多个条件SELECT * FROM emp WHERE age > 25 AND dept = 'IT';注意优先级,复杂逻辑建议加括号。

5.3 GROUP BY 与聚合函数

聚合函数语法用途代码示例注意事项
计数COUNT(*), COUNT(col)统计行数或非空值数量SELECT dept, COUNT(*) FROM emp GROUP BY dept;COUNT(*) 包含 NULL,COUNT(col) 不包含。
求和SUM(col)数值列求和SELECT dept, SUM(salary) FROM emp GROUP BY dept;仅适用于数值类型。
最大值MAX(col)获取最大值SELECT MAX(age) FROM emp;支持数值、字符串、日期等类型。
最小值MIN(col)获取最小值SELECT MIN(salary) FROM emp;同上。
平均值AVG(col)计算平均值SELECT AVG(salary) FROM emp;结果为 DECIMAL 类型,避免精度丢失。
去重计数COUNT(DISTINCT col)统计唯一值数量SELECT COUNT(DISTINCT dept) FROM emp;内存消耗大,大数据量建议使用近似函数 NDV()
分组查询GROUP BY col1, col2按一或多列分组聚合SELECT dept, gender, AVG(salary) FROM emp GROUP BY dept, gender;SELECT 中非聚合列必须出现在 GROUP BY 中。

5.4 HAVING 过滤聚合结果

语法项语法格式用途代码示例注意事项
HAVING 子句HAVING condition对 GROUP BY 后的结果进行过滤SELECT dept, AVG(salary) FROM emp GROUP BY dept HAVING AVG(salary) > 8000;HAVING 用于过滤聚合值,WHERE 用于过滤原始数据。
使用聚合函数HAVING COUNT(*) > 5基于统计结果过滤SELECT dept FROM emp GROUP BY dept HAVING COUNT(*) > 10;HAVING 条件中必须使用聚合函数或分组列。
多条件组合HAVING cond1 AND cond2组合多个过滤条件SELECT dept, AVG(salary) FROM emp GROUP BY dept HAVING AVG(salary) > 5000 AND COUNT(*) > 5;支持逻辑运算符。
与 WHERE 区别WHERE 在分组前过滤,HAVING 在分组后过滤先执行 WHERE,再 GROUP BY,最后 HAVING。

5.5 ORDER BY 与 LIMIT

子句语法格式用途代码示例注意事项
排序ORDER BY col [ASC|DESC]按列排序结果集SELECT * FROM emp ORDER BY salary DESC;默认升序 ASC;多列排序时按顺序生效。
多列排序ORDER BY col1, col2 DESC按多个字段排序SELECT * FROM emp ORDER BY dept, salary DESC;先按 dept 升序,再按 salary 降序。
限制行数LIMIT N返回前 N 行SELECT * FROM emp LIMIT 10;常用于分页或查看样本数据。
分页查询LIMIT offset, countLIMIT count OFFSET offset实现分页SELECT * FROM emp LIMIT 10 OFFSET 20;大偏移量(offset 很大)性能差,建议用游标或时间戳分页。
排序+限制ORDER BY ... LIMIT N获取 Top-N 结果SELECT name, salary FROM emp ORDER BY salary DESC LIMIT 5;Doris 会对该类查询进行优化。

5.6 JOIN 操作:INNER、LEFT、RIGHT、FULL、CROSS

JOIN 类型语法格式用途代码示例注意事项
内连接INNER JOINJOIN返回两表匹配的行SELECT * FROM A JOIN B ON A.id = B.a_id;最常用,性能较好。
左外连接LEFT JOINLEFT OUTER JOIN返回左表全部行,右表无匹配则补 NULLSELECT * FROM A LEFT JOIN B ON A.id = B.a_id;常用于查找”未关联”数据。
右外连接RIGHT JOINRIGHT OUTER JOIN返回右表全部行,左表无匹配则补 NULLSELECT * FROM A RIGHT JOIN B ON A.id = B.a_id;可通过交换表顺序用 LEFT JOIN 替代。
全外连接FULL JOINFULL OUTER JOIN返回两表所有行,无匹配则补 NULLSELECT * FROM A FULL JOIN B ON A.id = B.a_id;性能较差,内存消耗大,慎用。
交叉连接CROSS JOIN 或逗号返回两表笛卡尔积SELECT * FROM A CROSS JOIN B;行数 = A行数 × B行数,极易导致 OOM,避免使用。
ON 条件ON col1 = col2指定连接条件ON A.id = B.a_id必须包含等值条件;支持多列。
USING 子句USING (col)简化同名列连接SELECT * FROM A JOIN B USING (id);要求两表该列名相同。

5.7 子查询与 CTE(Common Table Expressions)

结构语法格式用途代码示例注意事项
标量子查询(SELECT col FROM table WHERE ...)返回单值,用于表达式SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp);必须返回单行单列,否则报错。
行子查询(SELECT col1, col2 FROM ...)返回单行多列SELECT * FROM emp WHERE (dept, salary) = (SELECT dept, MAX(salary) FROM emp GROUP BY dept);较少使用,需确保返回一行。
表子查询FROM (SELECT ...)作为临时表使用SELECT t.dept, t.cnt FROM (SELECT dept, COUNT(*) cnt FROM emp GROUP BY dept) t;必须为子查询指定别名。
CTE(WITH)WITH cte_name AS (SELECT ...)定义命名临时结果集见下方示例可提高可读性,支持递归(有限)。
关联子查询子查询引用外层表列实现逐行判断SELECT e1.name FROM emp e1 WHERE e1.salary > (SELECT AVG(salary) FROM emp e2 WHERE e2.dept = e1.dept);性能较差,尽量改写为 JOIN。

CTE 示例:

WITH top_salaries AS (
    SELECT * FROM emp ORDER BY salary DESC LIMIT 10
)
SELECT * FROM top_salaries;

5.8 窗口函数(Window Functions)基础

函数类别语法格式用途代码示例注意事项
排名函数ROW_NUMBER(), RANK(), DENSE_RANK()行内排名SELECT name, salary, RANK() OVER (ORDER BY salary DESC) rk FROM emp;ROW_NUMBER 不跳号,RANK 跳号,DENSE_RANK 不跳号。
分布函数PERCENT_RANK(), CUME_DIST()计算相对位置SELECT name, salary, PERCENT_RANK() OVER (ORDER BY salary) pct FROM emp;用于统计分布。
前后行函数LAG(col, n), LEAD(col, n)访问前/后第 n 行SELECT date, sales, LAG(sales, 1) OVER (ORDER BY date) prev_sales FROM daily_sales;常用于同比、环比计算。
聚合窗口函数SUM(...) OVER (...), AVG(...) OVER (...)窗口内聚合SELECT dept, name, salary, SUM(salary) OVER (PARTITION BY dept) dept_total FROM emp;支持所有聚合函数作为窗口函数。
窗口定义OVER ([PARTITION BY ...] [ORDER BY ...] [frame_clause])定义窗口范围SUM(sales) OVER (PARTITION BY region ORDER BY date ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)frame_clause 控制窗口行范围。

第六章:数据模型与高级特性

6.1 Aggregate 模型原理与使用场景

概念说明注意事项
核心原理相同主键的数据在导入时自动按指定聚合函数合并(如 SUM、REPLACE、MAX)适用于指标类数据(如 PV、UV、销售额)。
聚合列定义非主键列必须声明聚合方式,如 SUM(sales), MAX(last_visit)建表时必须明确每个非主键列的聚合函数。
导入合并导入时 Doris 自动查找相同主键行并合并查询时无需 GROUP BY 主键,性能高。
适用场景日志聚合、指标统计表、预聚合宽表不适用于需要保留明细的场景。
局限性无法还原原始明细数据;不支持 UPDATE/DELETE 操作一旦聚合,原始数据不可见。

6.2 Unique 模型:主键更新机制

特性说明注意事项
主键唯一性每行数据由主键唯一标识,新数据覆盖旧数据实现”UPSERT”语义。
更新方式导入时按主键查找并替换整行支持 Stream Load、Broker Load、Routine Load。
存储模式从 1.0 版本起支持 Merge-on-Write 或 Write-on-Read建议开启 enable_unique_key_merge_on_write 提升查询性能。
删除支持DELETE FROM table WHERE key = val; 可删除指定行必须包含所有主键列在 WHERE 中。
适用场景用户档案表、订单状态更新、缓慢变化维(SCD)替代传统数据库实现轻量级实时更新。

6.3 Duplicate 模型:明细数据存储

特性说明注意事项
数据存储不做任何聚合或去重,原始数据全部保留适合存储日志、行为事件等明细数据。
建表语法使用 DUPLICATE KEY(...) 或省略 KEY 定义默认模型,无需特殊声明。
查询灵活性支持任意维度的 GROUP BY 和聚合适合即席查询和灵活分析。
存储开销存储成本高,无自动压缩需依赖列存压缩和分区管理控制成本。
适用场景用户行为日志、交易流水、原始数据接入层通常作为数据仓库的明细层(DWD)。

6.4 物化视图(Materialized View)创建与管理

操作语法用途代码示例注意事项
创建物化视图CREATE MATERIALIZED VIEW mv_name AS SELECT ...预计算并存储查询结果见下方示例自动加速匹配的查询。
查询自动路由查询时自动匹配物化视图无需修改 SQLSELECT dept, SUM(salary) FROM emp GROUP BY dept; → 自动命中 emp_mv要求查询可被物化视图覆盖。
查看物化视图SHOW MATERIALIZED VIEWS;列出所有物化视图SHOW MATERIALIZED VIEWS FROM db;可查看状态、刷新方式等。
删除物化视图DROP MATERIALIZED VIEW mv_name;删除指定物化视图DROP MATERIALIZED VIEW emp_mv;删除后不再加速相关查询。
刷新机制自动同步基础表数据变更导入时自动更新物化视图不支持异步刷新,保证一致性。

创建物化视图示例:

CREATE MATERIALIZED VIEW emp_mv
AS SELECT dept, SUM(salary) sum_sal
FROM emp GROUP BY dept;

6.5 Rollup 表的构建与查询加速原理

概念说明注意事项
Rollup 表基于原表的列子集构建的聚合表,用于加速特定查询类似物化视图,但仅支持基于分桶列的聚合。
创建语法ALTER TABLE table ADD ROLLUP rollup_name (col1, col2, ...);添加 Rollup 表
查询加速查询时自动匹配最合适的 Rollup 表无需修改 SQL
数据同步导入时自动更新 Rollup 数据保证一致性
删除 RollupALTER TABLE table DROP ROLLUP rollup_name;移除 Rollup 表

第七章:性能调优与运维管理

7.1 查询性能分析:EXPLAIN 与 PROFILE

操作语法用途代码示例注意事项
查看执行计划EXPLAIN SELECT ...显示 SQL 的逻辑执行计划EXPLAIN SELECT * FROM emp WHERE id = 1001;分析是否命中索引、分区、Rollup 等。
查看详细 ProfileSHOW PROFILE 或访问 Web UI查看物理执行耗时、算子统计执行查询后:SHOW PROFILE;需开启 enable_profile = true(默认开启)。
Profile 内容项Fragment, Instance, Operator, Actual Rows, Total Time定位性能瓶颈(如扫描、Join、Sort)关注 Conjuncts(过滤条件)、Cardinality(行数估算)。
启用向量化分析EXPLAIN (FORMAT JSON) SELECT ...获取 JSON 格式执行计划EXPLAIN (FORMAT JSON) SELECT ...用于程序解析或深度分析。
分析延迟原因结合 EXPLAIN 和 PROFILE 判断:扫描数据量大、Join 倾斜、内存不足导致 Spill大表 Join 建议使用 Colocate Join 或 Bucket Shuffle Join。

7.2 分区与分桶设计优化

设计原则说明注意事项
分区策略选择按时间(DAY/MONTH)、按地域/业务线(LIST)建议使用 RANGE 分区,便于生命周期管理;避免过多小分区(>1000)。
分区粒度DAY > HOUR > MONTH(按数据量权衡)日增数据 < 1GB 可按月;>10GB 建议按天或小时。
分区剪枝WHERE 条件包含分区列可跳过无关分区WHERE dt = '2025-01-01' 可剪枝;WHERE substring(dt,1,7)='2025-01' 无法剪枝。
分桶列选择选择高基数、常用于等值条件或 Join 的列(如 user_id避免低基数列(如 gender)导致数据倾斜。
桶数设置建议为 BE 节点数的 110 倍,总桶数 10100 倍数据量示例:3 BE 节点 → 每表 10~30 桶;大表可设 100+ 桶。
动态分区配置使用 PROPERTIES 自动管理未来分区见下方示例

动态分区配置示例:

PROPERTIES (
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.buckets" = "10"
);

7.3 索引机制:前缀索引与 Bloom Filter

索引类型说明代码示例注意事项
前缀索引Doris 自动为排序列前 36 字节创建前缀索引,加速等值和范围查询建表时 KEY 列即为排序列:DUPLICATE KEY(k1, k2) → 索引 k1, k2前缀索引仅对排序列有效;建议将高频过滤列放在前面。
Bloom Filter用于快速判断某值是否存在,减少无效扫描PROPERTIES ("bloom_filter_columns" = "user_id,email");仅支持等值查询(=、IN);不支持字符串前缀匹配。
索引生效条件WHERE 包含前缀列或 Bloom Filter 列WHERE user_id = 1001 → 触发 Bloom Filter复合条件中需包含索引列。
查看索引效果通过 EXPLAIN 查看 PREDICATES 和 CARDINALITY若 CARDINALITY 估算准确,说明索引有效估算偏差大可能影响 Join 策略选择。
索引限制不支持二级索引;Bloom Filter 不支持 LIKE、!=大宽表建议合理设计列序和索引列。

7.4 BE 存储路径管理与扩容

操作语法/配置用途注意事项
配置存储路径be.conf 中设置:storage_root_path = /path/to/storage,medium=SSD指定 BE 数据存储目录及介质类型可配置多个路径,用逗号分隔;推荐使用 SSD。
查看路径状态SHOW PROC '/backends';查看 BE 节点存储使用情况关注 DataUsedCapacity、DiskUsedPercent。
添加新路径修改 be.conf 并重启 BE扩展单节点存储容量新路径需有足够权限,格式正确。
BE 扩容部署新 BE 节点 → 启动 BE → FE 自动注册增加集群存储和计算能力扩容后数据会自动均衡(需时间)。
数据均衡策略FE 自动调度 Tablet 均衡分布避免数据倾斜可通过 ADMIN SHOW REPLICA 查看分布。
缩容 BEALTER SYSTEM DROP BACKEND "host:port";移除 BE 节点确保数据已迁移完成,避免数据丢失。

7.5 FE 高可用配置(Follower 与 Observer)

角色说明配置方式注意事项
Leader处理元数据写操作(建表、导入等)自动选举产生仅有一个 Leader。
Follower参与选举,可处理元数据读操作fe.conf 中设置 edit_log_port = 9010;启动多个 FE 并通过 mysql -h fe_host -P 9010 -u root 添加至少 3 个 Follower 实现高可用(共 3~5 个 FE)。
Observer仅同步元数据,不参与选举,用于扩展读能力配置同 Follower,启动后执行:ALTER SYSTEM ADD OBSERVER "host:9010";适用于元数据读压力大的场景。
元数据同步使用 BDBJE 实现日志复制确保 edit_log_port 网络互通。
高可用部署推荐 3 FE(1 Leader + 2 Follower)+ N BE实现 FE 和 BE 层高可用避免 FE 单点故障。
查看 FE 状态SHOW PROC '/frontends';确认角色和存活状态Role 列显示 LEADER、FOLLOWER、OBSERVER。

7.6 监控指标与日志查看

监控项查看方式说明注意事项
FE 监控Web UI: http://fe_host:8030;Metrics: http://fe_host:8030/metrics查看查询 QPS、导入速率、元数据大小可集成 Prometheus + Grafana。
BE 监控Web UI: http://be_host:8040;Metrics: http://be_host:8040/metrics查看磁盘使用、查询延迟、内存占用关注 tablet_writer 性能。
查询日志fe/log/fe.warn.log, be/log/be.INFO定位错误和慢查询fe.audit.log 记录所有 SQL(需开启)。
慢查询日志开启 qe_slow_log_ms(如 1000ms)记录超过阈值的查询日志位于 fe/log/ 目录下。
告警配置结合 Prometheus + Alertmanager设置磁盘、CPU、查询延迟告警生产环境必备。
常用命令SHOW PROC '/statistic'; SHOW PROC '/current_tasks';查看集群统计和当前任务用于实时诊断。

第八章:安全与权限管理

8.1 用户与角色管理(CREATE USER、GRANT、REVOKE)

操作语法用途代码示例注意事项
创建用户CREATE USER 'user'@'host' [IDENTIFIED BY 'password'];添加新用户CREATE USER 'analyst'@'%' IDENTIFIED BY '123456';'host' 支持 %(任意)、192.168.%(网段)。
删除用户DROP USER 'user'@'host';删除用户DROP USER 'test'@'%';删除后其权限自动清除。
创建角色CREATE ROLE role_name;定义角色便于权限管理CREATE ROLE analyst_role;角色可跨用户复用。
授予角色GRANT role_name TO 'user'@'host';将角色分配给用户GRANT analyst_role TO 'analyst'@'%';用户可拥有多个角色。
查看用户权限SHOW GRANTS FOR 'user'@'host';显示用户拥有的权限SHOW GRANTS FOR 'analyst'@'%';包括直接权限和角色继承权限。

8.2 权限体系详解(数据库、表、资源级权限)

权限类型支持对象语法示例说明注意事项
GLOBAL 级集群级资源GRANT ADMIN PRIVILEGES ON *.* TO user;超级管理员权限包含所有权限,慎用。
DATABASE 级数据库GRANT SELECT ON DATABASE db1 TO user;控制数据库操作权限可授 SELECT, INSERT, ALTER, DROP 等。
TABLE 级GRANT SELECT, INSERT ON TABLE tbl1 TO user;精细化控制表操作最常用权限粒度。
RESOURCE 级外部资源(如 Spark、HDFS)GRANT USAGE ON RESOURCE 'spark01' TO user;控制资源使用权限用于 Broker Load、Spark Load 等场景。
USAGE 权限数据库/资源GRANT USAGE ON DATABASE db1 TO user;允许访问数据库(但不能查表)通常与表权限配合使用。
撤销权限REVOKE privilege ON object FROM user;移除用户权限REVOKE INSERT ON TABLE tbl1 FROM 'user'@'%';撤销后立即生效。

8.3 认证方式配置(LDAP、SSL 等简介)

认证方式配置说明用途注意事项
原生密码认证默认方式,用户密码存储在 FE 元数据中简单易用建议定期修改密码。
LDAP 认证配置 auth_type = ldapfe.conf集成企业 LDAP/AD 统一认证需配置 LDAP 服务器地址、DN、搜索过滤器。
SSL 加密连接配置 SSL 证书,启用 enable_ssl加密客户端与 FE 之间通信提升数据传输安全性,防止窃听。
Kerberos(有限支持)结合 Hadoop 生态使用企业级安全认证Doris 原生支持较弱,通常通过 Broker 层实现。
密码策略通过 PASSWORD_HISTORYPASSWORD_LOCK_TIME 等属性增强密码安全性SET PASSWORD_POLICY = ...(部分版本支持)。
安全建议禁用 root 远程登录;使用最小权限原则;启用审计日志提升整体安全性生产环境必须配置访问白名单和监控告警。

第九章:生态集成与外部数据源

9.1 外部表(External Table)概述

概念说明注意事项
外部表定义不在 Doris 中存储数据,仅保存元数据和连接信息,查询时实时访问外部系统实现”读时建模”(Schema-on-Read)
支持类型MySQL、Kafka(通过 Routine Load)、Hive / Iceberg / Hudi、JDBC 兼容数据库统一通过 Catalog 机制管理
查询方式SELECT * FROM external_table;语法与本地表一致
适用场景实时查看业务库数据、联邦查询 Hive 数仓、流式数据接入避免频繁全表扫描外部大表
优势无需导入即可查询、实时性高、减少数据冗余

9.2 MySQL 外部表配置与查询

操作语法/配置用途代码示例注意事项
创建 CatalogCREATE EXTERNAL CATALOG mysql_catalog PROPERTIES (...);定义 MySQL 数据源连接见下方示例支持批量映射多个表。
查询外部表SELECT * FROM mysql_cat.table_name;查询 MySQL 表数据SELECT * FROM mysql_cat.user_info WHERE id = 1001;支持 WHERE 下推,减少网络传输。
查看 CatalogSHOW CATALOGS;SHOW TABLES FROM mysql_catalog;列出所有 Catalog 或表SHOW TABLES FROM mysql_cat;确认表是否成功加载。
谓词下推自动将 WHERE 条件下推到 MySQL 执行提升查询效率WHERE create_time > '2025-01-01' → 在 MySQL 端过滤不支持复杂函数下推。
性能建议避免全表扫描;使用索引列过滤;控制返回字段减少对源库压力可结合物化视图缓存热点数据。

创建 MySQL Catalog 示例:

CREATE EXTERNAL CATALOG mysql_cat
PROPERTIES (
    "type" = "mysql",
    "mysql.host" = "192.168.1.10",
    "mysql.port" = "3306",
    "mysql.user" = "root",
    "mysql.password" = "123456",
    "database" = "test_db"
);

9.3 Kafka 与 Routine Load 集成

操作语法用途代码示例注意事项
创建 Routine LoadCREATE ROUTINE LOAD db.job_name ON tbl_name FROM KAFKA (...);从 Kafka 持续消费数据并导入 Doris见下方示例支持 Exactly-Once 语义。
查看任务状态SHOW ROUTINE LOAD FOR job_name;监控消费进度、错误日志SHOW ROUTINE LOAD FOR kafka_job;关注 CurrentTaskStatus、DataProcessed。
暂停/启动任务PAUSE/RESUME ROUTINE LOAD FOR job_name;控制导入流程PAUSE ROUTINE LOAD FOR kafka_job;维护时可暂停。
错误处理设置 max_error_number容忍部分数据错误PROPERTIES ("max_error_number" = "1000")超过阈值任务会暂停。
数据格式支持 CSV、JSON、AVRO、Parquet灵活解析 Kafka 消息PROPERTIES ("format" = "json")JSON 需配置 json_rootjsonpaths
位点管理自动提交消费位点(offset)保证不丢不重停止任务后重新启动会从上次位点继续。

创建 Routine Load 示例:

CREATE ROUTINE LOAD example_db.kafka_job ON user_log
COLUMNS TERMINATED BY ",",
COLUMNS (user_id, event_type, ts),
PROPERTIES ("desired_concurrent_number"="1"),
FROM KAFKA (
    "kafka_broker_list" = "broker1:9092,broker2:9092",
    "kafka_topic" = "doris_log",
    "kafka_partitions" = "0,1,2",
    "kafka_offsets" = "OFFSET_BEGINNING"
);

9.4 Hive / Iceberg / Hudi 外部表接入

格式配置方式用途注意事项
Hive 外部表创建 Hive Catalog,连接 Hive Metastore查询 Hive 表数据见下方示例
Iceberg 外部表创建 Iceberg Catalog,指定 Metastore 或 File-based查询 Iceberg 表见下方示例
Hudi 外部表创建 Hudi Catalog,连接 Hive Metastore查询 Hudi MOR/COW 表见下方示例
共同特性支持分区裁剪、谓词下推、列式扫描优化提升大数据查询效率查询性能依赖 HDFS/S3 访问速度。
使用建议避免频繁全表扫描;使用分区列过滤;结合 Colocate Join 加速关联分析可通过物化视图预聚合结果。

Hive Catalog 示例:

CREATE EXTERNAL CATALOG hive_cat
PROPERTIES (
    "type" = "hive",
    "hive.metastore.uris" = "thrift://hms:9083"
);

Iceberg Catalog 示例:

CREATE EXTERNAL CATALOG iceberg_cat
PROPERTIES (
    "type" = "iceberg",
    "iceberg.catalog.type" = "hive",
    "iceberg.catalog.uri" = "thrift://hms:9083"
);

Hudi Catalog 示例:

CREATE EXTERNAL CATALOG hudi_cat
PROPERTIES (
    "type" = "hudi",
    "hive.metastore.uris" = "thrift://hms:9083"
);

9.5 JDBC Catalog 使用

操作语法用途代码示例注意事项
创建 JDBC CatalogCREATE EXTERNAL CATALOG jdbc_cat PROPERTIES (...);接入任意 JDBC 兼容数据库见下方示例需上传 JDBC 驱动到 FE lib 目录。
查询外部数据SELECT * FROM jdbc_cat.schema.table;执行远程查询SELECT * FROM pg_catalog.public.users WHERE status = 1;支持标准 SQL 语法。
驱动管理手动上传 .jar 文件至 fe/lib/加载数据库驱动wget https://repo1.maven.org/.../postgresql-42.5.0.jar -P fe/lib/重启 FE 生效。
性能限制网络延迟高,不适合大数据量扫描适用于维表关联、小表查询建议用于 Dimension 表而非 Fact 表。
安全配置支持 SSL 连接参数加密传输jdbc.url 中添加 ?ssl=true&...需数据库端支持 SSL。

创建 JDBC Catalog 示例:

CREATE EXTERNAL CATALOG pg_catalog
PROPERTIES (
    "type" = "jdbc",
    "jdbc.url" = "jdbc:postgresql://192.168.1.10:5432/test",
    "jdbc.user" = "user",
    "jdbc.password" = "pass",
    "jdbc.driver_url" = "postgresql-42.5.0.jar",
    "jdbc.driver_class" = "org.postgresql.Driver"
);

第十章:最佳实践与常见问题

10.1 表设计最佳实践

设计项推荐做法说明注意事项
数据模型选择明细数据 → Duplicate;指标聚合 → Aggregate;主键更新 → Unique根据业务需求选择错误模型导致无法更新或查询慢。
分区设计按时间分区(如 dt DATE),粒度按数据量定(日/小时)便于生命周期管理和查询剪枝分区数不宜过多(<1000)。
分桶设计选择高基数列(如 user_id),桶数 = BE 数 × (1~10)避免数据倾斜,提升并行度建议总桶数在 10~100 倍 BE 数之间。
排序列(KEY)将高频过滤、Group By、Join 列放在前面提升前缀索引命中率前 36 字节用于索引。
属性配置设置 replication_num=3,启用 Bloom Filter提升可用性和查询性能生产环境必须多副本。
建表模板使用 SHOW CREATE TABLE 导出标准建表语句统一团队建表规范避免随意建表导致管理混乱。

10.2 导入性能优化建议

优化方向建议措施说明
导入方式选择实时小批量 → Stream Load;离线大批量 → Broker Load;流式数据 → Routine Load匹配场景选择最优方式
并发控制提高并发任务数和单任务并发度desired_concurrent_number 控制 Routine Load 并发
批量大小Stream Load 单次 100MB~1GB;Broker Load 分片导入避免过小(开销大)或过大(超时)
数据格式使用列式格式(Parquet/ORC)替代 CSV减少网络传输和解析开销
错误容忍设置 max_filter_ratio > 0容忍少量脏数据,避免任务失败
资源隔离为导入任务分配独立线程池或队列避免影响查询性能
监控告警监控导入延迟、失败率、吞吐量及时发现异常

10.3 查询性能调优案例

问题现象可能原因解决方案
查询慢(>10s)未命中分区/分桶;全表扫描;Join 倾斜检查 WHERE 是否包含分区列;使用 EXPLAIN 分析执行计划;改写为 Colocate Join
内存溢出(OOM)大表 Join;大量去重(COUNT DISTINCT);排序数据量大增加 BE 内存;使用 NDV() 替代 COUNT(DISTINCT);启用 mem_limit 限制单查询内存
查询延迟高集群负载高;磁盘 I/O 瓶颈;网络延迟查看 BE CPU/Disk 使用率;升级 SSD;优化网络环境
结果不一致导入未完成;缓存未刷新等待导入完成;使用 REFRESH MATERIALIZED VIEW
无法命中 Rollup查询列不匹配;聚合方式不同检查 Rollup 定义;确保查询可被覆盖

10.4 常见错误码与解决方案

错误码/信息原因解决方案
errCode = 2, detailMessage = TabletNotFoundTablet 未找到(副本缺失)检查 BE 是否宕机,等待自动恢复或手动修复
errCode = 410, detailMessage = Failed to send batchBE 写入失败检查 BE 存储空间、网络、日志
Max filter ratio exceeded数据质量差,错误行超过阈值清洗数据或提高 max_filter_ratio
Transaction already committed重复提交相同 Label更换导入 Label
Memory limit exceeded查询内存超限优化 SQL 或调整 exec_mem_limit
Can't find partition分区不存在或已删除检查分区名、时间范围
User has no access权限不足使用 GRANT 授予权限
Broker does not existBroker 未部署或宕机检查 Broker 服务状态

10.5 集群备份与恢复策略

策略方法说明注意事项
元数据备份备份 FE 元数据目录(fe/palo-meta/包含表结构、用户、权限等停止 FE 后备份,或使用 ADMIN REPAIR 命令
数据备份使用 EXPORT 命令导出数据;复制 HDFS/S3 上的 Tablet 数据实现全量或增量备份EXPORT 支持 Parquet/CSV 格式
快照备份ALTER TABLE tbl1 SNAPSHOT ...创建数据快照Doris 2.0+ 支持
恢复方式重建集群 + 导入备份数据;使用 RESTORE 命令(未来支持)当前主要依赖重导
定期任务使用脚本 + cron 定时备份自动化运维建议每日备份元数据,每周全量数据
灾备方案搭建异地 Doris 集群,通过 Routine Load 或 Kafka 同步实现高可用延迟取决于同步机制