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