更新时间:2025-09-16 GMT+08:00
分享

使用DWS行列共存表

场景介绍

在实际业务场景中,一张表往往既需要支持高并发的点查与更新(如订单、账单、日志等),也需要支持高效的批量查询与聚合分析(如统计报表、趋势分析)。传统的行存与列存各有所长:

  • 行存(Row Store):适合点查、写入频繁的实时场景,如根据订单号查询订单详情。
  • 列存(Column Store):适合大批量分析型查询,如统计一段时间内的总交易额。

DWS提供的行列共存表(也称行列混存表),是一种创新的混合存储模式:在一张表中同时存储行格式数据和列格式数据,两种格式各自独立维护、同步更新,由查询优化器根据实际查询路径选择最优访问方式。

其核心优势在于:

  • 无需拆表或复制数据:一张表即同时支持明细查询与批量分析。
  • 由系统自动选择最优路径:查询点查字段时走行存,查询聚合字段时走列存,无需额外开发处理。
  • 性能最优兼顾:在不牺牲OLTP性能的同时,兼具OLAP查询效率。
  • 兼容原有行表设计:无需调整应用结构,快速享受列存优化/行存优化带来的性能收益。
  • 统一管理、降低运维成本:一张物理表即覆盖两种场景,简化数据同步、备份与权限控制。

本最佳实践文档将介绍如何设计使用行列共存表结构,结合典型场景和性能对比,帮助您在业务系统中实现更高效的数据处理能力。

实时场景下表类型对比(行存表 / 列存表 / 行列共存表)

表1 实时场景下表类型对比

对比维度

行存表(orientation='row')

HStore表(hstore_opt表)

行列共存表(storage_mode='mix')

存储架构

原生行存引擎(不基于列存)

HStore_opt列存

自研行模式和列存HStore_opt表共存

点查性能(主键)

 极优(5)

 较差(2)

 优(4)

批量入库性能

 较差(2)

 极优(5)

 优(4)

实时入库性能

 极优(5)

 极优(5)

 极优(5)

聚合/分析性能

⬛ 差(1)

 极优(5)

 极优(5)

空间占用

⬛ 高(1)

 极低(5)

 一般(3)

空间膨胀

 极优(5)

 极优(5)

 优(4)

DWS列存特殊优化

❌ 不支持

✅ 支持

✅ 支持

约束限制

  • 仅9.1.1.100及以上版本支持
  • 需使用HStore表,即enable_hstore_opt参数设置为开。
  • 不支持存算分离V3表。
  • 不支持开启HStore表的enable_light_update选项。
  • 不支持binlog表,物化视图。
  • 小批量的实时copy入库,相比HStore表,存在10%的性能劣化。
  • 行列混存表只能和行列混存表进行exchange,扩容重分布后,禁止使用exchange。

使用建议

  • 仅OLTP场景(例如高频点查、写入):若对空间使用敏感,推荐使用行列共存表,兼顾空间与点查性能的折中方案,若空间不敏感,追求极致效果的场景推荐行存表。
  • 仅OLAP场景(例如统计分析、报表):推荐使用HStore的列存表。
  • 明细与统计查询并存,且字段冷热难以区分:推荐使用行列共存表模式,各个场景性能最优;
  • 实时入库上,推荐使用PBE AddBatch方式入库。
  • 建议不要轻易修改列定义,若触发数据重写,行列共存表会重写行存部分整个数据,性能开销较大。

语法参考

以下是创建行列共存表语法,更多请参见CREATE TABLE语法章节(仅9.1.1.100及以上版本支持)。

1
2
3
4
5
6
7
8
CREATE TABLE <表名> (
    <列定义>
)
WITH (
    orientation = column,          -- 基于列式的存储架构
    enable_hstore_opt = on,        -- 开启 hstore_opt 能力
    storage_mode = 'mix'           -- 指定建立行列共存表
);

示例

-- 行列共存模式:同时存储行格式与列格式数据,适用于明细+分析混合业务
CREATE TABLE tbl_mix (
    a INT,
    b TEXT
)
WITH (
    orientation = column,
    enable_hstore_opt = on,
    storage_mode = 'mix'
);

使用行列混存表示例

  1. 建立一个简单的数据表。

    1
    2
    3
    DROP TABLE IF EXISTS data;
    CREATE TABLE data(a INT, b BIGINT, c VARCHAR(10), d VARCHAR(10));
    INSERT INTO data values(generate_series(1,100),1,'asdfasdf','gergqer');
    

  2. 扩充表数据至20W。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    INSERT INTO data SELECT * FROM data;
    SELECT COUNT(*) FROM data;
    

  3. 构造一个简单的行列共存表。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    DROP TABLE IF EXISTS rowmode_test1;
    CREATE TABLE rowmode_test1 (
        a INT,
        b BIGINT,
        c VARCHAR(10),
        d VARCHAR(10)
    )
    WITH (
        orientation = column,
        enable_hstore_opt = on,
        storage_mode = 'mix'
    );
    

  4. 将数据导入行列共存表。

    1
    INSERT INTO rowmode_test1 SELECT * FROM data;
    

相关文档