You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OceanBase中INSERT INTO...SELECT启用direct load反而慢2.4倍的原因咨询

OceanBase Direct Load在INSERT INTO...SELECT中性能反降的问题分析与最佳实践

问题描述

测试OceanBase的direct load特性时发现,启用direct load的INSERT INTO...SELECT查询执行时间是传统路径的2.4倍。根据官方文档,direct load可绕过SQL层直接写入数据文件,理论上应具备更优的大规模数据导入性能,但实际测试结果与预期相悖。

环境信息

  • OceanBase版本:OceanBase Community v4.3.5.0
  • OLAP租户创建命令:
obd cluster tenant create obtest -n test --max-cpu=28 --memory-size=98G --zone-list=zone1,zone2,zone3 --primary-zone=RANDOM \
--locality=F@zone1,F@zone2,F@zone3 --charset=utf8 -s 'ob_tcp_invited_nodes="%"' --optimize=olap
  • 调整的配置参数:
set global parallel_servers_target = 560;
ALTER SYSTEM SET default_table_store_format = 'row';
SET GLOBAL parallel_degree_policy = MANUAL;

测试步骤

  • 使用sysbench为3张表各准备1000万行数据
  • 创建目标表tmp1:CREATE TABLE tmp1 LIKE sbtest1;
  • 删除目标表主键的自增属性:ALTER TABLE tmp1 MODIFY id int(11) NOT NULL;
  • 对比测试两种插入路径:
    1. 传统路径(10.24秒):
    insert /*+ enable_parallel_dml parallel(16) no_direct */ into tmp1 select * from sbtest1;
    
    1. Direct Load路径(24.42秒):
    insert /*+ enable_parallel_dml parallel(16) DIRECT(true, 0, 'full') */ into tmp1 select * from sbtest1;
    
  • 添加NO_GATHER_OPTIMIZER_STATISTICS hint后性能无明显差异:
    insert /*+ enable_parallel_dml parallel(16) DIRECT(true, 0, 'full') NO_GATHER_OPTIMIZER_STATISTICS */ into tmp1 select * from sbtest1; -- 24.58秒
    insert /*+ enable_parallel_dml parallel(16) no_direct NO_GATHER_OPTIMIZER_STATISTICS */ into tmp1 select * from sbtest1; -- 10.45秒
    

问题原因分析

  1. 数据规模不匹配:direct load的设计目标是超大规模数据导入(通常亿级以上),1000万数据量下,direct load的初始化开销、文件写入后的合并操作开销,反而超过了其绕过SQL层带来的收益;而传统路径依赖内存批量写入+提交,在中小数据量下效率更高。
  2. 存储格式适配问题:direct load对columnar存储格式的优化远优于row格式,本次测试中目标表使用row格式,无法发挥direct load的核心优势。
  3. 约束校验开销:目标表保留了主键约束,direct load需要额外执行全局唯一性校验,这部分开销远大于传统路径的批量校验逻辑。
  4. 并行度配置不合理:设置的parallel(16)与direct load的调度机制不匹配,过高的并行度导致资源竞争,反而降低了写入效率。

Direct Load搭配INSERT INTO...SELECT的限制

  • 仅在**超大规模数据(亿级以上)**场景下能体现性能优势,中小数据量下可能反降
  • 对columnar存储格式优化显著,row格式下性能提升有限
  • 目标表存在主键/唯一键时,会触发额外的全局唯一性校验,大幅增加开销
  • 不支持带复杂计算、多表关联的SELECT语句,仅适合简单全表扫描或轻过滤查询
  • 并行度需与集群资源匹配,过高或过低都会影响性能

最佳实践

  1. 选对数据规模:仅当导入数据量达到亿级以上时,再考虑使用direct load
  2. 使用columnar存储:创建目标表时指定STORE_FORMAT='columnar',例如:
    CREATE TABLE tmp1 LIKE sbtest1 STORE_FORMAT='columnar';
    
  3. 临时移除约束:导入前删除目标表的主键、唯一键,导入完成后再重建,避免唯一性校验开销
  4. 优化并行度:根据集群CPU核心数调整并行度,建议设置为核心数的1-2倍,例如28核集群设置parallel(28)或parallel(56)
  5. 配合专业导入工具:direct load搭配外部导入工具(如OBLOADER)的效果优于INSERT INTO...SELECT,工具会更高效地处理数据分块与写入调度
  6. 简化SELECT语句:避免在SELECT中加入复杂计算、多表关联,让direct load专注于数据写入环节

内容的提问来源于stack exchange,提问作者user30132773

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:19:57