AnalyticDB PostgreSQL支持多种存储格式。当您创建一个表时,可以选择表的存储格式为行存表或者列存表。

行存表

默认情况下,AnalyticDB PostgreSQL创建的是行存表。行存表使用和 PostgreSQL 相同的堆存储模型(Heap Table),在 OLTP 类型负载下表现最好:这种场景中,数据常由每次一行或几行的 INSERT 实时插入,且在初始插入后可能被频繁地修改或删除。如有较小的表(例如维度表),建议选择行存表。同时,当行存表建有于B-Tree索引时,具备更好的点查询数据检索性能。

说明 当采用数据传输服务DTS写入AnalyticDB PostgreSQL时,AnalyticDB PostgreSQL的目标表建议设计为行存表,而不要采用列存表。DTS为准实时数据同步的方式,除INSERT外,同时支持UPDATE和DELETE等较多更新操作的同步。

下述语句创建了一个默认堆存储类型的行存表 foo。

CREATE TABLE foo (a int, b text)
DISTRIBUTED BY (a);

列存表

列存表(Column-Oriented Table)的按列存储格式,数据访问只会读取涉及的列,适合少量列的数据查询、聚集等数据仓库应用场景,在此类场景中,列存表能够提供更高效的 I/O。但列存表不适合频繁的更新操作或者大批量的INSERT写入场景,这时其效率较低。列存表的数据写入建议采用 COPY 等批量加载方式。列存表可以提供平均 3~5倍的较高数据压缩率。

列存表必须是追加优化表,即要创建一个列存表,必须指定为 "appendonly=true"。

下述语句创建了一个列存表bar。

CREATE TABLE bar (a int, b text)
WITH (appendonly=true, orientation=column)
DISTRIBUTED BY (a);

选择面向行或者面向列的存储

行存表和列存表的选择需根据实际负载而定,在为一个表决定存储格式时,建议参考下列需求:

  • 对于大部分常用目的或者混合负载,行存表兼顾了灵活性和性能。
  • 如果会频繁地一条或几条地插入数据、已有数据会被频繁的修改和删除,请考虑行存表。
  • 如果基本是大批量地导入数据,且已有数据很少被修改和删除,请考虑列存表。
  • 如果查询的投影列表或者条件语句中常常要求所有或者大部分列,或者表的行尺寸相对较小时,请考虑行存表;相反,如果表具有很多列,且查询常常访问这些列的一个小子集时,请考虑列存表。
  • 空间占用考虑:列存表中的每一列具有相同的数据类型,便于使用临近数据的相似性来进行压缩,因此在空间占用上比行存表更有优势;另一方面,压缩做得越好,随机访问就会越困难。

修改表的存储格式

表存储格式(行存或列存)只能在创建表时声明。要改变存储模型,必须使用目标的存储格式创建一个表,将原始表的数据载入到新表中,删除原始表,并把新表重命名为原始表的名称。用户还必须重新授权原始表上有的权限。注意这个过程不是原子的,为保证数据完整性,需要业务侧保证在修改的过程中对原始表只读。

将行存表foo重新载入为列存表。

CREATE TABLE foo_tmp (LIKE foo) WITH (appendonly=true, orientation=column);
INSERT INTO foo_tmp SELECT * FROM sales;
DROP TABLE foo;
ALTER TABLE foo_tmp RENAME TO foo;

GRANT ALL PRIVILEGES ON foo TO user1;
GRANT SELECT ON foo TO user2;