1. MySQL兼容性概述
Apache Doris高度兼容MySQL协议和语法,但存在一些重要差异。理解这些差异对于从MySQL迁移到Doris或进行混合部署至关重要。
1.1. 数据类型差异对比
1.1.1. 数字类型差异
| 类型 | MySQL支持 | Doris支持 | 关键差异 |
|---|---|---|---|
| Boolean | 支持(0=false, 1=true) | 支持(0=false, 1=true) | 完全兼容 |
| Bit | 支持(1-64位) | 不支持 | 显著差异 |
| Tinyint | 支持signed/unsigned | 仅支持signed | 范围差异 |
| Smallint | 支持signed/unsigned | 仅支持signed | 范围差异 |
| Mediumint | 支持 | 不支持 | 显著差异 |
| Int | 支持signed/unsigned | 仅支持signed | 范围差异 |
| Bigint | 支持signed/unsigned | 仅支持signed | 范围差异 |
| Largeint | 不支持 | 支持(-2127~2127-1) | Doris特有 |
| Decimal | 支持signed/unsigned | 仅支持signed | 默认值不同 |
1.1.2. 日期类型差异
| 类型 | MySQL支持 | Doris支持 | 关键差异 |
|---|---|---|---|
| Date | '1000-01-01'~'9999-12-31' | '0000-01-01'~'9999-12-31' | 范围更广 |
| DateTime | 支持精度参数P | 支持精度参数P | 范围更广 |
| Timestamp | 支持 | 不支持 | 显著差异 |
| Time | 支持 | 不支持 | 显著差异 |
| Year | 支持 | 不支持 | 显著差异 |
1.1.3. 字符串类型差异
| 类型 | MySQL支持 | Doris支持 | 关键差异 |
|---|---|---|---|
| Char | M为字符长度 | M为字节长度 | 定义不同 |
| Varchar | M为字符长度 | M为字节长度 | 定义不同 |
| String | 不支持 | 支持(1MB~2GB) | Doris特有 |
| Binary/Varbinary | 支持 | 不支持 | 显著差异 |
| Blob/Text | 支持 | 不支持 | 显著差异 |
| Enum/Set | 支持 | 不支持 | 显著差异 |
| JSON | 支持 | 支持 | 完全兼容 |
1.2. Doris特有数据类型
Doris特有数据类型 HyperLogLog HLL BITMAP QUANTILE_STATE Array MAP STRUCT Agg_State 模糊去重 1-2%误差 精确去重 全局字典 分位数计算 数组类型 映射类型 结构体类型 聚合状态类型
特有类型使用限制:
- 不能作为Key列使用
- 需要配合特定聚合函数
- 有各自的误差和性能特性
1.3. 语法差异
1.3.1. DDL差异
CREATE TABLE主要差异:
sql
-- Doris建表示例
CREATE TABLE [IF NOT EXISTS] [database.]table
(
column_definition_list
[, index_definition_list]
)
[engine_type] -- OLAP引擎
[keys_type] -- 数据模型:DUPLICATE/AGGREGATE/UNIQUE
[table_comment]
[partition_info] -- 分区算法
[distribution_desc] -- 分桶算法(必选)
[rollup_list] -- 物化视图
[properties]
[extra_properties]
关键差异点:
- 数据模型:Doris有DUPLICATE/AGGREGATE/UNIQUE KEY模型
- 分桶算法:Doris必须指定分桶(Hash/Random)
- 物化视图:Doris支持同步/异步物化视图
- 存储引擎:Doris主要是OLAP引擎
1.3.2. DML差异
UPDATE语句:
sql
-- Doris UPDATE必须包含WHERE条件
UPDATE target_table [table_alias]
SET assignment_list
WHERE condition; -- 必须包含
DELETE语句限制:
- 不能过于频繁(分析型数据库特性)
- 支持两种语法:简单谓词和USING子句(仅Unique Key表)
1.3.3. SQL Mode支持
| 模式名称 | 作用 | 备注 |
|---|---|---|
| PIPES_AS_CONCAT | 将丨解析为concat函数 | 默认解析为逻辑或 |
| NO_BACKSLASH_ESCAPES | 反斜杠作为普通字符 | 默认作为转义字符 |
| ONLY_FULL_GROUP_BY | 严格GROUP BY检查 | 3.1.0+支持 |
2. JOIN操作详解
2.1. JOIN类型概述
JOIN类型 INNER JOIN LEFT JOIN RIGHT JOIN FULL JOIN CROSS JOIN LEFT SEMI JOIN RIGHT SEMI JOIN LEFT ANTI JOIN RIGHT ANTI JOIN NULL AWARE LEFT ANTI JOIN 返回匹配行 左表全量 + 右表匹配 右表全量 + 左表匹配 左右全量合并 笛卡尔积 存在匹配则返回左表行 存在匹配则返回右表行 无匹配则返回左表行 无匹配则返回右表行 特殊处理NULL值
2.2. JOIN物理实现
2.2.1. Hash Join vs Nest Loop Join
| 特性 | Hash Join | Nest Loop Join |
|---|---|---|
| 适用条件 | 等值JOIN条件 | 所有JOIN场景 |
| 性能 | 通常更好 | 可能较差 |
| 内存使用 | 需要构建哈希表 | 流式处理 |
| 适用场景 | 等值比较 | 非等值比较、笛卡尔积 |
2.2.2. Hash Join Shuffle方式对比
详细对比表:
| Shuffle方式 | 网络开销 | 适用场景 | 限制条件 |
|---|---|---|---|
| Broadcast | N × T® | 通用场景 | 不支持RIGHT OUTER/ANTI/SEMI |
| Partition Shuffle | T(S) + T® | 通用场景 | 仅限Hash Join |
| Bucket Shuffle | T® | JOIN条件含左表分桶列 | 等值JOIN、OLAP表、单分区 |
| Colocate | 0 | 同Colocate Group表 | 分桶列类型/数量一致、Colocate Group稳定 |
2.3. 优化JOIN示例
2.3.1. Bucket Shuffle Join示例
sql
-- 创建测试表
CREATE TABLE t1 (
c1 BIGINT,
c2 BIGINT
) DISTRIBUTED BY HASH(c1) BUCKETS 3
PROPERTIES ("replication_num" = "1");
CREATE TABLE t2 (
c1 BIGINT,
c2 BIGINT
) DISTRIBUTED BY HASH(c1) BUCKETS 3
PROPERTIES ("replication_num" = "1");
-- Bucket Shuffle Join查询
EXPLAIN SELECT *
FROM (
-- t1表按c1哈希分布,GROUP BY后仍保持
SELECT c1 AS c1, SUM(c2) AS c2
FROM t1
GROUP BY c1
) tx
JOIN (
-- t2表按c1哈希分布,GROUP BY后变为按c2分布
SELECT c2 AS c2, SUM(c1) AS c1
FROM t2
GROUP BY c2
) ty ON tx.c1 = ty.c2; -- JOIN条件满足Bucket Shuffle
执行计划关键点:
- 左侧数据保持不动
- 右侧数据通过Exchange节点分发
- 使用
BUCKET_SHUFFLE标识
2.3.2. Colocate Join示例
sql
-- Colocate Join查询
EXPLAIN SELECT *
FROM (
-- 两个子查询结果都按c2哈希分布
SELECT c2 AS c2, SUM(c1) AS c1
FROM t1
GROUP BY c2
) tx
JOIN (
SELECT c2 AS c2, SUM(c1) AS c1
FROM t2
GROUP BY c2
) ty ON tx.c2 = ty.c2; -- JOIN条件满足Colocate
执行计划关键点:
- 无Exchange节点
- 两侧数据都保持原位
- 使用
PARTITIONED标识 - 直接在本地进行Hash Join
2.4. JOIN性能优化指南
是 否 是 否 小 大 JOIN性能优化 数据分布检查 是否同Colocate Group? 使用Colocate Join JOIN条件含分桶列? 使用Bucket Shuffle Join 右表数据量大小? 使用Broadcast Join 使用Partition Shuffle Join 最优: 零网络开销 较优: 仅移动右表 通用: 广播右表 通用: 双侧Shuffle 性能最佳
2.5. 限制与注意事项
2.5.1. Bucket Shuffle Join限制
- 等值JOIN条件:仅支持等值比较
- 分桶列要求:JOIN条件须包含分桶列
- 表类型限制:仅限Doris OLAP表
- 单分区要求:左表需为单分区(通过WHERE分区裁剪)
2.5.2. Colocate Join限制
- 分桶一致性:分桶列类型和数量必须一致
- Colocate Group:需显式指定相同Colocate Group
- 稳定性要求:Group处于稳定状态(非副本修复/均衡期间)
3. 迁移与兼容性建议
3.1. MySQL到Doris迁移检查清单
| 检查项 | MySQL特性 | Doris对应 | 迁移动作 |
|---|---|---|---|
| 数据类型 | BIT, MEDIUMINT | 不支持 | 转换类型或应用层处理 |
| 日期类型 | TIMESTAMP, TIME | 不支持 | 使用DATETIME或应用层转换 |
| 字符串类型 | BLOB, TEXT | 不支持 | 使用STRING类型 |
| 索引类型 | B+Tree, Hash | 位图/倒排/N-Gram | 重新设计索引策略 |
| 存储引擎 | InnoDB, MyISAM | OLAP引擎 | 重新设计表结构 |
| 事务隔离 | 多级别支持 | READ COMMITTED | 应用层调整 |
3.2. JOIN优化实践建议
-
表设计阶段
- 根据JOIN模式设计分桶列
- 相关表使用相同Colocate Group
- 合理设置分桶数量(避免过少影响并行度)
-
查询编写阶段
- 优先使用等值JOIN条件
- 利用分区裁剪减少数据量
- 避免不必要的CROSS JOIN
-
性能监控阶段
- 监控SHUFFLE数据量
- 检查JOIN类型选择是否合理
- 分析执行计划中的Exchange节点
3.3. 兼容性配置建议
sql
-- 设置SQL Mode以兼容MySQL行为
SET sql_mode = 'PIPES_AS_CONCAT,NO_BACKSLASH_ESCAPES';
-- 对于GROUP BY严格检查
SET sql_mode = 'ONLY_FULL_GROUP_BY'; -- 3.1.0+支持
-- 调整JOIN相关会话变量
SET enable_bucket_shuffle_join = true;
SET enable_colocate_join = true;
SET parallel_fragment_exec_instance_num = 8; -- 调整并行度
4. 总结
4.1. 关键差异汇总
- 数据类型:Doris不支持BIT、TIMESTAMP等,但有HLL、BITMAP等特有类型
- 存储模型:Doris有独特的数据模型和分桶概念
- JOIN优化:Doris提供多种Shuffle方式优化分布式JOIN
- SQL扩展:Doris支持物化视图、导出等OLAP特性
4.2. 最佳实践选择
OLTP事务处理 OLAP分析查询 关联表同分布 左表分桶列JOIN 小表关联大表 通用大表关联 使用场景 数据处理类型 使用MySQL 使用Doris JOIN优化选择 Colocate Join Bucket Shuffle Join Broadcast Join Partition Shuffle Join 完成选择
4.3. 版本注意事项
- 3.1.0+:支持ONLY_FULL_GROUP_BY SQL Mode
- 2.1.11/3.0.7+:取消导出文件2GB限制
- 各版本在数据类型支持和JOIN优化上可能有差异