Hybrid DML 是 Hologres 自研的新一代数据写入引擎,通过自适应决策引擎统一处理 INSERT、UPDATE、DELETE 等 DML 操作,从根本上解决大表导入场景下的 OOM 问题。
功能概述
什么是 Hybrid DML
Hybrid DML 是 Hologres 自研的新一代数据写入引擎,用于处理 INSERT、INSERT ON CONFLICT、UPDATE、DELETE 等 DML 操作。它将原来分散在多个算子中的写入逻辑统一为一个智能算子(DataSetHybridDMLNode),能根据实际数据量自适应选择最优的 Join 和去重策略,从根本上解决了大表导入场景下的 OOM(内存溢出)问题。
简单来说:
老 DML:优化器(QO)预先决定 Join 算法,执行引擎(SE)按固定计划执行。当数据量超出预期时,容易发生 OOM。
新 Hybrid DML:执行引擎(SE)根据实时数据量自适应选择 Join 策略,确保不 OOM,做到"可慢不可挂"。
核心价值
维度 | 老 DML | Hybrid DML |
稳定性 | 大表导入可能 OOM | 自适应策略切换,保证不 OOM |
性能 | 依赖优化器预估,预估不准则性能差 | 运行时自适应,性能更稳定 |
易用性 | 需要 DBA 手动调整 Join 策略 | 自动选择,无需人工干预 |
执行计划 | 4 种 DML 算子,计划复杂 | 1 种统一算子,计划简洁 |
用户收益
稳定性提升
在老 DML 引擎下,当源表(如 MaxCompute 外表)数据量很大且目标表也有大量已有数据时,Hash Join 的 Hash Table 可能超出内存限制,导致 query 甚至 worker OOM。
Hybrid DML 通过内置的自适应决策引擎(Game Machine),在数据逐批写入过程中实时监控内存使用:
数据量小:使用 Hash Join,性能最优。
数据量中等:自动切换 Hash Join 的 Build 侧(把更小的数据集作为 Hash Table)。
数据量大:自动降级为 Sort-Merge Join(支持落盘),保证不 OOM。
性能优化
场景 | 收益说明 |
小表导入 | 与老 DML 性能持平(走 Hash Join 路径)。 |
大表导入(原本 OOM) | 从失败变为成功完成,吞吐约为 Hash Join 的 1/3。 |
INSERT ON CONFLICT DO UPDATE(全列更新) | 触发 Blind Merge 优化,跳过 Join,性能大幅提升。 |
Dynamic Table 增量刷新 | 默认走 Hybrid DML,增量写入更高效。 |
使用方法
开启与关闭
语法完全不变,仍然是标准的 INSERT、UPDATE、DELETE 语句。Hybrid DML 通过 GUC 参数控制是否启用:
Hologres V3.1 及以上版本默认开启 Hybrid DML,无需手动设置即可生效。
-- 开启 Hybrid DML(V3.1 及以上版本默认开启)
SET hg_experimental_enable_hybrid_dml = on;
-- 关闭 Hybrid DML,回退到老 DML 引擎
SET hg_experimental_enable_hybrid_dml = off;使用示例
-- 确保开启 Hybrid DML
SET hg_experimental_enable_hybrid_dml = on;
-- 普通导入
INSERT INTO holo_table SELECT * FROM mc_table;
-- 带主键的 Upsert
INSERT INTO holo_table
SELECT * FROM source_table
ON CONFLICT (pk_col) DO UPDATE SET
col1 = EXCLUDED.col1,
col2 = EXCLUDED.col2;
-- 忽略冲突
INSERT INTO holo_table
SELECT * FROM source_table
ON CONFLICT (pk_col) DO NOTHING;
-- 从 Paimon 外表导入
INSERT INTO holo_table SELECT * FROM paimon_table;核心 GUC 参数一览
参数名 | 类型 | 默认值 | 说明 |
| bool |
| Hybrid DML 总开关。 |
| bool |
| UPDATE 修改主键列时是否使用 Hybrid DML(默认回退老路径)。 |
| bool |
| 是否启用 Runtime Filter(Bloom Filter)加速 Hash Join。 |
| enum |
| 手动指定 Join 策略(一般不需要修改)。 |
Join 策略枚举值说明(hg_experimental_hybrid_dml_join_mode):
值 | 含义 | 适用场景 |
| 自适应选择(推荐)。 | 绝大多数场景。 |
| 强制使用 Sort-Merge Join(支持落盘)。 | 内存极度紧张或调试。 |
| 强制使用 Hash Join,自动选择 Build 侧。 | 确认数据量不会 OOM。 |
| 强制源数据为 Probe 侧(目标表建 Hash Table)。 | 目标表较小。 |
| 强制目标表为 Probe 侧(源数据建 Hash Table)。 | 源数据较小。 |
最佳实践:保持 auto 模式,让系统自适应选择。
版本行为差异
各版本默认行为
版本 | 默认行为 | 说明 |
Hologres V3.0 及以下版本 | 不支持 Hybrid DML | 仅使用老 DML 引擎。 |
Hologres V3.1 及以上版本 | Hybrid DML 默认开启 | 无需手动设置,所有 DML 默认走 Hybrid 路径。 |
功能演进
功能点 | Hologres V3.0 及以下版本 | Hologres V3.1 及以上版本 |
普通 INSERT | 不支持 | 默认开启 |
INSERT ON CONFLICT DO UPDATE | 不支持 | 默认开启 |
INSERT ON CONFLICT DO NOTHING | 不支持 | 默认开启 |
DELETE | 不支持 | 默认开启 |
UPDATE(非主键列) | 不支持 | 默认开启 |
UPDATE(主键列) | 不支持 | 需额外开启 |
Blind Merge 优化 | 不支持 | 自动触发(全列 UPDATE 场景) |
Dynamic Table 增量刷新 | 老路径 | 默认使用 Hybrid DML |
Runtime Filter 加速 | 不支持 | 默认开启 |
Sort-Merge Join 降级 | 不支持 | 自动触发(大表场景) |
如何判断当前是否使用 Hybrid DML
使用 EXPLAIN 查看执行计划:
EXPLAIN INSERT INTO holo_table SELECT * FROM source_table;Hybrid DML 计划:包含
DataSetHybridDMLNode节点。老 DML 计划:包含
DataSetInsertNode、DataSetDeleteNode、DataSetUpdateNode或DataSetMergeNode。
更详细的计划(含 Protobuf 格式):
EXPLAIN (FORMAT PB) INSERT INTO holo_table SELECT * FROM source_table;工作原理(面向 DBA)
自适应 Join 决策流程
Hybrid DML 的自适应决策引擎在数据写入过程中实时做出决策,流程如下:
关键决策点:
源数据量 < 目标表数据量:将源数据缓存到 Buffer Table,到达末尾(EOS)后以源数据建 Hash Table,扫描目标表做 Probe → RIGHT OUTER JOIN。
目标表数据量 < 源数据量:扫描目标表建 Hash Table,源数据做 Probe → LEFT OUTER JOIN。
内存不足:自动降级为 Sort-Merge Join,两侧分别排序后归并 → 支持落盘,不会 OOM。
Runtime Filter 加速
当使用 Hash Join 且源数据作为 Build 侧时,Hybrid DML 会自动生成 Runtime Filter:
Rowgroup Filter:将源数据的主键值转为 IN-list 过滤条件,下推到目标表的存储层,跳过不相关的 Row Group。
Bloom Filter:对主键列构建 Bloom Filter,在扫描目标表时提前过滤不匹配的行。
触发条件(默认阈值):
目标表行数 ≥ 10,000 行。
源数据行数 < 目标表行数 × 0.3。
Blind Merge 优化
当 INSERT ON CONFLICT DO UPDATE 满足以下条件时,触发 Blind Merge 优化,完全跳过目标表 Join:
UPDATE SET 子句覆盖了所有非主键列。
主键列在 SET 子句中使用恒等表达式(如
pk = EXCLUDED.pk)。不包含子查询等复杂表达式。
Blind Merge 的效果等价于:既然无论如何都会更新所有列,就不需要先读目标表的旧值,直接覆写即可。
限制与约束
功能限制
限制项 | 说明 |
仅限离线导入 | 不支持 Fixed Plan(在线点查点写)。 |
UPDATE 主键列 | 默认不走 Hybrid DML,需额外开启 |
含子查询的 ON CONFLICT | 如果 |
INSERT OVERWRITE | 源端去重策略仅支持 |
性能预期
场景 | 性能预期 |
小数据量导入(内存可容纳) | 与老 DML 的 Hash Join 路径性能持平。 |
大数据量导入(触发 Sort-Merge Join) | 吞吐约为 Hash Join 的 1/3,但能保证不 OOM。 |
Blind Merge 场景 | 优于老 DML(跳过 Join)。 |
兼容性
不影响其他功能:Hybrid DML 与老 DML 引擎完全隔离,关闭 GUC 即可回退。
不破坏兼容性:SQL 语法完全不变,对用户透明。
向前兼容:老版本能跑的场景,新版本行为一致。
监控与排查
执行计划解读
EXPLAIN INSERT INTO target_table
SELECT * FROM source_table
ON CONFLICT (pk) DO UPDATE SET col1 = EXCLUDED.col1;Hybrid DML 执行计划示例:
Insert on target_table
-> DataSetHybridDMLNode -- Hybrid DML 算子
Join Strategy: Auto -- 自适应 Join
Dedup Action: Throw -- 源端去重策略
Memory Quota: 2048 MB -- 内存配额
Runtime Filter: Enabled -- Runtime Filter 开启
-> Seq Scan on source_table老 DML 执行计划示例(对比):
Insert on target_table
-> DataSetInsertNode -- 老 Insert 算子
-> Hash Left Join -- 固定 Join 策略
-> Seq Scan on source_table
-> Seq Scan on target_table关键区别:
Hybrid DML 只有一层算子,Join 策略内置。
老 DML 有独立的 Join 算子,策略由优化器预先决定。
查看实际选择的 Join 策略
使用 EXPLAIN (FORMAT PB) 可以看到详细的 Protobuf 格式计划,其中包含:
实际选择的 Join 策略(
join_strategy字段)。源端去重动作(
source_deduplicate.action字段)。Runtime Filter 配置(
runtime_filter_options字段)。内存配额(
memory_quota字段)。
最佳实践
日常使用建议
保持默认配置:Hologres V3.1 及以上版本默认开启 Hybrid DML,
join_mode保持auto,绝大多数场景无需调整。大表导入无需额外操作:不再需要手动估算数据量来选择 Join 策略。
Dynamic Table 场景:增量刷新已默认使用 Hybrid DML,无需额外配置。
性能调优建议
场景 | 建议 |
内存充足时大表导入慢 | 调大 |
确认源数据无重复 | 设置 |
全列更新场景 | 确保 UPDATE SET 覆盖所有非主键列,触发 Blind Merge 优化。 |
回退方案
如果遇到 Hybrid DML 相关问题,可以随时回退:
-- 会话级回退
SET hg_experimental_enable_hybrid_dml = off;
-- 数据库级回退(需 Superuser 权限),新建连接生效
ALTER DATABASE dbname SET hg_experimental_enable_hybrid_dml = off;回退后所有 DML 操作将使用老 DML 引擎,SQL 语法无需任何修改。
附录:GUC 参数完整参考
参数名 | 类型 | 默认值 | 范围 | 说明 |
| bool | on | session / database | Hybrid DML 总开关。 |
| enum | auto | session | Join 策略选择。 |
| bool | off | session | UPDATE 主键列时启用 Hybrid DML。 |
| bool | on | session | 启用 Runtime Filter。 |
| bool | on | session | 优化器提取 Hybrid DML 过滤条件。 |
| int | 70 | 0–100 | 自适应成本模型中 CPU 时间权重。 |
| bool | off | session | 禁用源端去重。 |
| bool | off | session | 普通表 Blind Merge 开关。 |
| bool | on | session | Dynamic Table 增量刷新使用 Hybrid DML。 |