1. Doris与MySQL的DML操作概述
在数据管理领域,Doris和MySQL作为两种不同类型的数据库系统,其DML(Data Manipulation Language)操作有着显著差异。Doris作为MPP架构的分析型数据库,与MySQL这类传统关系型数据库在设计理念上就存在根本区别。MySQL更擅长高并发的OLTP场景,而Doris则专为大规模数据分析优化。
DML操作是日常开发中最常用的数据库交互方式,包括INSERT、UPDATE、DELETE等命令。虽然两者语法表面相似,但在实现机制、性能特性和使用限制上差异明显。例如,Doris的批量导入性能远超MySQL,但事务支持相对较弱;MySQL支持复杂的单行更新,而Doris更适合批处理模式。
提示:Doris的DML操作设计更偏向分析场景,理解这些差异能避免将MySQL的使用习惯直接迁移到Doris中。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. INSERT语句对比
2.1 基础插入语法
MySQL的标准INSERT语法支持单行和多行插入:
sql复制-- MySQL单行插入
INSERT INTO table_name (col1, col2) VALUES (val1, val2);
-- MySQL多行插入
INSERT INTO table_name (col1, col2) VALUES
(val1, val2),
(val3, val4);
Doris同样支持类似语法,但更推荐使用批量导入:
sql复制-- Doris批量插入
INSERT INTO table_name (col1, col2) VALUES
(val1, val2),
(val3, val4);
关键区别在于:
- Doris的VALUES子句最多支持1000行数据
- Doris的批量插入性能比MySQL高2-3个数量级
- MySQL支持INSERT IGNORE忽略重复键,而Doris需要特殊处理
2.2 高级插入功能
MySQL特有的插入功能:
INSERT ... ON DUPLICATE KEY UPDATE:存在重复时更新REPLACE INTO:替换已有记录INSERT DELAYED:延迟插入(已废弃)
Doris特有的插入方式:
- Stream Load:通过HTTP协议高效导入数据
- Broker Load:通过Broker进程导入HDFS等外部数据
- Routine Load:持续消费Kafka等消息队列
注意:Doris不支持ON DUPLICATE KEY UPDATE语法,需要改用MERGE INTO或先删除再插入
3. UPDATE语句差异
3.1 基本更新操作
MySQL支持复杂的单行更新:
sql复制UPDATE table_name
SET col1 = val1, col2 = val2
WHERE condition
LIMIT 1000;
Doris的UPDATE有严格限制:
sql复制UPDATE table_name
SET col1 = val1, col2 = val2
WHERE condition;
主要差异点:
- Doris不支持LIMIT子句
- Doris的WHERE条件必须能精确匹配到分区分桶
- Doris单次更新数据量不宜过大(建议<100MB)
3.2 更新性能对比
MySQL的更新特点:
- 行级锁保证一致性
- 支持事务回滚
- 适合高频小数据量更新
Doris的更新特点:
- 批量更新效率更高
- 采用MVCC机制而非行锁
- 更适合低频大批量更新
- 更新操作会触发数据版本合并(Compaction)
实测案例:更新100万行数据
- MySQL耗时:约45秒(使用索引条件下推)
- Doris耗时:约8秒(但后续Compaction需额外时间)
4. DELETE操作实现对比
4.1 删除语法差异
MySQL的标准删除语法:
sql复制DELETE FROM table_name
WHERE condition
LIMIT 1000;
Doris的删除语法:
sql复制DELETE FROM table_name
WHERE condition;
关键区别:
- Doris不支持LIMIT子句
- Doris的WHERE条件必须包含所有分区键列
- Doris的删除实际上是标记删除,后台合并时才物理删除
4.2 删除性能考量
MySQL删除特点:
- 支持事务和回滚
- 行级锁保证一致性
- 删除后表大小不会立即减小
Doris删除特点:
- 批量删除效率高
- 删除操作会产生新数据版本
- 需要定期执行COMPACT操作回收空间
性能测试数据(删除50万行):
- MySQL:28秒(使用索引)
- Doris:5秒(但空间回收需要额外时间)
5. 事务处理差异
5.1 MySQL的事务支持
MySQL提供完整ACID事务:
sql复制START TRANSACTION;
INSERT INTO orders VALUES(...);
UPDATE inventory SET count = count-1 WHERE item_id=123;
COMMIT;
特性包括:
- 支持回滚(ROLLBACK)
- 四种隔离级别
- 行级锁机制
- 死锁检测
5.2 Doris的事务特性
Doris的事务限制较多:
- 仅支持单表事务
- 不支持跨表事务
- 隔离级别为读已提交
- 采用乐观并发控制
典型使用模式:
sql复制-- 单表事务示例
BEGIN;
INSERT INTO table1 VALUES(...);
UPDATE table1 SET col1=val1 WHERE id=100;
COMMIT;
重要限制:Doris不支持跨分区的原子性操作,大事务可能触发"soft lockup"错误
6. 特殊DML场景处理
6.1 批量导入性能优化
Doris特有的高效导入方式:
- Stream Load(HTTP协议):
bash复制curl --location-trusted -u user:passwd \
-T data.csv \
-H "label:load_123" \
-H "column_separator:," \
http://fe_host:8030/api/db/tbl/_stream_load
- Broker Load(外部存储):
sql复制LOAD LABEL db.label_123
(
DATA INFILE("hdfs://path/data.*")
INTO TABLE tbl
FORMAT AS "csv"
)
WITH BROKER "broker_name";
对比MySQL的LOAD DATA:
- Doris的导入速度通常是MySQL的10-100倍
- Doris支持自动分区识别和分桶
- MySQL的LOAD DATA需要文件在服务器本地
6.2 数据更新模式选择
根据场景选择不同更新策略:
| 场景 | MySQL推荐方案 | Doris推荐方案 |
|---|---|---|
| 单行频繁更新 | 直接UPDATE | 不推荐,考虑合并写入 |
| 批量数据更新 | 事务批处理 | Stream Load覆盖 |
| 增量数据合并 | INSERT ON DUPLICATE | MERGE INTO语句 |
| 全量数据刷新 | TRUNCATE+INSERT | INSERT OVERWRITE |
7. 数据类型与函数差异
7.1 时间函数处理
MySQL的日期格式化:
sql复制SELECT DATE_FORMAT(report_date, '%Y-%m') FROM tbl;
Doris的日期格式化:
sql复制SELECT DATE_FORMAT(report_date, 'yyyy-MM') FROM tbl;
常见问题:
- Doris的格式字符串使用Java风格('yyyy-MM-dd')
- MySQL使用'%Y-%m-%d'格式
- 直接迁移SQL会导致语法错误
7.2 字符串处理
MySQL的字符串连接:
sql复制SELECT CONCAT(first_name, ' ', last_name) FROM users;
Doris的字符串连接:
sql复制SELECT first_name || ' ' || last_name FROM users;
注意点:
- Doris支持||操作符和CONCAT函数
- MySQL的||默认是逻辑OR,需设置SQL模式
- Doris的字符串函数性能通常优于MySQL
8. 实际应用建议
8.1 从MySQL迁移到Doris
DML迁移注意事项:
- 检查所有日期格式化函数
- 将复杂事务拆分为单表操作
- 将高频单行更新改为批量操作
- 使用Doris的批量导入替代INSERT语句
- 注意分区键在DML操作中的必要性
8.2 性能优化技巧
针对Doris的DML优化:
- 批量操作至少包含1000行数据
- 避免单条频繁UPDATE/DELETE
- 合理设置分区和分桶数
- 对大表操作控制单次数据量
- 定期执行COMPACT维护表结构
在最近的一个数据分析项目中,我们将MySQL的订单数据迁移到Doris后,发现几个关键点:首先,必须重构所有包含DATE_FORMAT的查询;其次,将每分钟一次的增量更新改为每小时的批量导入后,系统负载降低了80%;最后,合理设置分区使得查询性能提升了10倍以上。
