暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

DM9 HTAP实测:同一个数据库实例同时跑交易与分析

原创 二两烧麦 2天前
39

一、 HTAP基础理论知识

  1. OLTP(联机事务处理)
    面向业务交易,典型场景是订单新增、修改、删除、用户提交业务单据。特点:短事务、单次操作数据量很小、并发高,对响应延迟、数据一致性要求严格。存储优先选用行存储,一条完整业务记录连续存放,单行增删改效率高。

  2. OLAP(联机分析处理)
    面向统计分析、报表、多维查询。典型场景:统计月度销售额、按维度聚合业务数据。特点:单次查询扫描大量数据,以读为主,大量分组、求和、计数聚合运算;对单行修改要求低。传统方案使用列存储,同一字段的数据集中存放,做聚合的时候只读取需要的字段,减少IO开销。

  3. HTAP(混合事务分析处理,Hybrid Transaction‑Analytical Processing)
    传统架构中OLTP和OLAP两套引擎割裂:交易库只适合业务,分析库靠ETL同步数据,会带来数据延迟、维护链路复杂。
    HTAP的目标就是在同一套数据库内核中同时支持OLTP事务写入更新 + OLAP分析查询,业务数据写入之后,分析查询可以直接读取最新数据,不需要额外做数据搬迁。

HTAP常见两种实现路线:

  • 双副本模式:数据库内部自动维护行存、列存两份数据,事务写入行存,分析读取列存副本,由数据库内部完成同步;
  • 行列融合存储:一套存储框架下,行存、列存数据物理共存,支持列存也可以做事务性增删改,不需要维护完整双副本。

注意:HTAP不等于列存表一定比行存表快,它是架构能力,实际性能会受数据量、访问模式、内存命中率影响。


二、底层存储布局

登录disql,查看数据库为HTAP准备的底层存储对象:

SELECT name, type$, status$ FROM v$tablespace; LINEID NAME TYPE$ STATUS$ 1 SYSTEM 1 0 2 ROLL 1 0 3 TEMP 2 0 4 MAIN 1 0

type$=1代表永久表空间,type$=2是临时表空间;status$=0代表状态ONLINE,这部分行为和DM8保持一致。

SELECT TABLESPACE_NAME, CONTENTS, STATUS FROM DBA_TABLESPACES;SELECT TABLESPACE_NAME, CONTENTS, STATUS FROM 

LINEID  TABLESPACE_NAME  CONTENTS   STATUS
1       SYSTEM           PERMANENT  ONLINE
2       ROLL             UNDO       ONLINE
3       TEMP             TEMPORARY  ONLINE
4       MAIN             PERMANENT  ONLINE
SELECT * FROM V$HUGE_TABLESPACE;

LINEID  ID  NAME  PATHNAME                  DIR_NUM  COPY_NUM  SIZE_MODE
1       4   MAIN  /dmdata/data/DM9/HMAIN    1        NULL      NULL

V$HUGE_TABLESPACE视图,MAIN表空间挂载了HMAIN目录/dmdata/data/DM9/HMAIN,这就是HUGE列存表实际存放数据的物理路径。

列存数据实际依托HUGE表、HMAIN目录来存放。

image.png

三、创建行存表与列存表

达梦列存表使用CREATE HUGE TABLE语法。我创建结构完全一样的一张普通行表、一张列存表,灌入相同数据(50万)做对比测试。

完整建表和插入数据SQL:

CREATE TABLE orders_row(oid INT, cust_id INT, status CHAR(1), amount DECIMAL(12,2), odate DATE, remark VARCHAR(200)); CREATE HUGE TABLE orders_col(oid INT, cust_id INT, status CHAR(1), amount DECIMAL(12,2), odate DATE, remark VARCHAR(200)) STORAGE(SECTION(65536), FILESIZE(64), WITH DELTA); INSERT INTO orders_row SELECT LEVEL, MOD(LEVEL,1000), CHR(65+MOD(LEVEL,26)), LEVEL*1.5, TO_DATE('2026-01-01','YYYY-MM-DD')+MOD(LEVEL,365), 'remark '||LEVEL FROM DUAL CONNECT BY LEVEL<=500000; COMMIT; INSERT INTO orders_col SELECT oid,cust_id,status,amount,odate,remark FROM orders_row; COMMIT;

image.png

各项操作耗时统计:

操作 耗时
建普通行表 orders_row 60.313 ms
建列存表 orders_col 9.447 ms
行表插入50万行 238.890 ms
列存表插入50万行 311.335 ms

四、确认列存数据真实物理位置

两张表建好之后,确认列存表数据到底存在哪里:

SELECT TABLE_NAME, TABLESPACE_NAME FROM USER_TABLES WHERE TABLE_NAME IN ('ORDERS_ROW','ORDERS_COL');

LINEID  TABLE_NAME  TABLESPACE_NAME
1       ORDERS_ROW  MAIN
2       ORDERS_COL  MAIN
SELECT COUNT(*) FROM orders_row;
COUNT(orders_row):  500000
SELECT COUNT(*) FROM orders_col;
COUNT(orders_col):  500000

image.png

从数据字典看,行表和列存表逻辑上都归属MAIN表空间。但逻辑归属不等于物理存放位置,我到操作系统层面查看HMAIN目录:

du -sh /dmdata/data/DM9/HMAIN; 
26M     /dmdata/data/DM9/HMAIN
ls -lh /dmdata/data/DM9/HMAIN
drwxr-xr-x 3 dmdba dinstall 21 Sep  5 13:03 SCH150994945

image.png

HMAIN目录占用26M,内部子目录SCH150994945创建时间正好是我往列存表导入数据的时刻。

由此可以确认:行存数据存放在MAIN表空间的数据文件中;列存HUGE表的数据,物理上独立保存在HMAIN目录下面
行存、列存共处同一个数据库实例,不需要跨库迁移数据,这就是官方说的行列融合存储在存储层的具体实现。

五、TP、AP业务混跑测试

HTAP的核心价值,就是同一套实例里面,交易业务和分析业务可以同时运行。我在库中交替执行OLTP单行事务操作,以及OLAP聚合查询。

OLTP单行事务测试SQL:

INSERT INTO orders_row VALUES(999999,1,'A',100.5,SYSDATE,'tp'); COMMIT;
UPDATE orders_row SET amount=amount+1 WHERE oid=999999;
COMMIT;
DELETE FROM orders_row WHERE oid=999999;
COMMIT;

image.png

TP操作耗时:

TP操作 耗时
单行INSERT 4.155 ms
单行UPDATE 15.641 ms
单行DELETE 16.239 ms

接下来做分组聚合分析查询,每条SQL执行两次,取稳定耗时:

SELECT cust_id, COUNT(*), SUM(amount) FROM orders_row GROUP BY cust_id; -- 行表 SELECT cust_id, COUNT(*), SUM(amount) FROM orders_col GROUP BY cust_id; -- 列存表

由于内容太长,无法进行截图,把结果列到表中。

操作 第1次 第2次
行表分组聚合 63.926 ms 75.684 ms
列存表分组聚合 84.415 ms 75.089 ms

测试结果:在分组聚合场景,列存表性能和行表几乎持平,第一次执行甚至更慢。

分析背后的原因:

  1. 本次50万行全部可以加载进数据库内存缓冲区,查询瓶颈在CPU计算、SQL解析,而不是磁盘IO。列存储“只读需要的列、压缩减少IO”的优势发挥不出来;
  2. 两张表都是全表扫描,数据全部命中内存buffer,存储带来的差异被抹平;
  3. 第一次执行包含硬解析开销,所以两次执行耗时存在波动。

这个实测结果:小数据量、全部数据命中内存、没有索引的场景,列存不一定执行的更快

六、验证列存的列投影优势

列存储最核心的优势就是列投影:查询只需要读取用到的字段,不用读取整行所有字段。对amount字段做求和,再次对比性能。

SELECT SUM(amount) FROM orders_row; -- 行表,跑两次 SELECT SUM(amount) FROM orders_row;
SELECT SUM(amount) FROM orders_col;   -- 列存表,跑两次
SELECT SUM(amount) FROM orders_col; 

image.png

操作 第1次 第2次
行表单列SUM 50.344 ms 51.455 ms
列存单列SUM 9.572 ms 8.007 ms

只做单字段求和,列存表性能大概是行表的6倍。
原理:列存只读取amount这一列压缩数据块;而行存储读取一条记录,会把一整行全部字段读到内存,再提取amount字段。数据量上来后,列存能够大幅降低IO读取量,这就是列投影的实际效果。

七、HTAP落地使用总结

结合理论和本次单机实测,对DM9 HTAP可以得到几个实操层面的判断:

  1. 存储架构:逻辑统一,物理隔离
    行存表和列存表,字典层面都归属MAIN表空间;但列存HUGE表实际物理数据独立保存在HMAIN目录。同一个实例中行存、列存并存,不需要把数据同步到另外一套数据库,这就是“行列融合存储”的落地形态。

  2. 列存性能有明确的触发条件,不是万能加速神器
    小数据量、数据全在内存中,列存优势并不明显,分组聚合甚至和行存差不多。
    当满足数据量大 + 查询只访问少数字段 + 查询会触发磁盘IO读取,列存的压缩、列投影优势才能体现出来,本次单列SUM测试达到约6倍性能差距。不能不管业务场景,无脑把业务表全部改成列存。

  3. 业务选型建议
    频繁单行新增、修改、删除的交易业务表,优先选择行存;
    以扫描、聚合统计为主的大表,很少单行更新,适合用WITH DELTA的HUGE列存表。行表列表可以部署在同一个DM9实例中,实现HTAP。
    如果业务规模继续扩大,部署DMDPC分布式集群,再叠加子计划级并行计算、负载均衡,才是完整HTAP能力。

最后修改时间:2026-09-11 09:59:05
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论