天天看点

Greenplum表存储模型选择

Greenplum表存储模型选择

    • 前言:
    • 堆存储:
    • AO表:
    • 行存:
    • 列存:
    • 查看表的存储结构:

前言:

Greenplum数据库支持多种存储模型和一种混合存储模型。当用户创建一个表时,用户会选择如何存储它的数据。本文主要解释表存储的选项以及如何为用户的负载选择最好的存储模型,Greenplum支持行存和列存,支持堆表和AO表。

堆存储:

1.堆表的原理:

堆表实际上就是PG的堆存储,堆表的所有变更都会产生REDO,可以实现时间点恢复。但是堆表不能实现逻辑增量备份(因为表的任意一个数据块都有可能变更,不方便通过堆存储来记录位点)。一个事务结束时,通过clog以及REDO来实现它的可靠性。同时支持通过REDO来构建MIRROR节点实现数据冗余。

2.堆表选择使用场景:

a. 数据写入时,小事务偏多时选择堆表(如:维度表)。

b. 要时间点恢复时,选择堆表。

  1. 堆表创建语法:

面向行的堆表是默认的存储类型

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

CREATE TABLE tbl_heap_row(a int, b text) with (appendonly=false);

AO表:

1.AO表的原理:

AO表是只追加的存储,删除更新数据时,通过另一个BITMAP文件来标记被删除的行,通过bit以及偏移对齐来判定AO表上的某一行是否被删除。事务结束时,需要调用FSYNC,记录最后一次写入对应的数据块的偏移(并且这个数据块即使只有一条记录,下次再发起事务又会重新追加一个数据块)同时发送对应的数据块给MIRROR实现数据冗余。因此AO表不适合小事务,因为每次事务结束都会FSYNC,同时事务结束后这个数据块即使有空余也不会被复用(AO表单条提交的IO放大很严重)。

AO表非常适合OLAP场景,批量的数据写入,高压缩比,逻辑备份支持增量备份,因此每次记录备份到的偏移量即可。加上每次备份全量的BITMAP删除标记(很小)。

2.AO表选择使用场景:

a.当需要列存时,选择AO表。

b.当数据批量写入时,选择AO表。

3.AO表创建语法:

a.数据表使用列存储AO表,列存、使用zlib算法5级压缩、指定分布键

create table tbl_ao_col(a int, b text) with (APPENDONLY=true, ORIENTATION=column,blocksize=8192,COMPRESSTYPE=zlib, COMPRESSLEVEL=5) DISTRIBUTED BY (a);

b.数据表使用列存储AO表,行存、不指定压缩、指定分布键

create table tbl_ao_row(a int, b text) with (APPENDONLY=true, ORIENTATION=row, COMPRESSTYPE=none) DISTRIBUTED BY (a);

① APPENDONLY仅追加:意思是只能Insert,不能update和delete(通过visimap来标记记录的可见性和是否已删除)。但是可以truncate。 由于常用开发不推荐update和delete操作(效率慢),所以一般数据表均要求为appendonly表

② ORIENTATION列存储:不启用的话默认为行存储。列模式对某一列进行查询或聚合,效率会很高。注意:采用列存储必须是appendonly表

③ COMPRESSTYPE压缩算法:有不同的压缩算法。目前要求只采用zlib算法。注意:采用压缩算法时必须是appendonly表,zlib: 缩小算法 quicklz: 快速压缩 RLE_TYPE: 游程编码 none: 无压缩。

④ COMPRESSLEVEL压缩级别:与压缩算法是关联的,数值范围在1-9。目前要求固定值为5

压缩表跟列存储来说,前提是必须是appendonly的表。

RLE_TYPE压缩:1–4(1是最快的方法但压缩率最低,4是最慢的方法但压缩率最高,1是默认值)

1-只应用RLE

2-应用RLE然后应用zlib压缩级别1

3-应用RLE然后应用zlib压缩级别5

4-应用RLE然后应用zlib压缩级别9

⑤ BLOCKSIZE表中每一块的以字节计的尺寸范围为:8192 – 2097152(该值必须是8192的倍数)。

行存:

1.行存原理:

以行为形式组织存储,一行是一个tuple,存在一起。当需要读取某列时,需要将这列前面的所有列都进行deform,所以访问第一列和访问最后一列的成本实际上是不一样的。

2.行存特点:

a.全表扫描要扫描更多的数据块。

b.压缩比较低。

c.读取任意列的成本不一样,越靠后的列,成本越高。

d.不适合向量计算、JIT架构。(简单来说,就是不适合批处理形式的计算)

e.需要REWRITE表时,需要对全表进行REWRITE,例如加字段有默认值。

3.行表选择使用场景:

OLTP的需求偏多,经常需要查询表的明细(输出很多列),需要更多的更新和删除操作时。可以考虑行存。

列存:

1.列存原理:

以列为形式组织存储,每列对应一个或一批文件。读取任一列的成本是一样的,但是如果要读取多列,需要访问多个文件,访问的列越多,开销越大。

2.列存特点:

a.仅仅支持AO存储。

b.读取任意列的成本是一样的。

c.非常适合向量计算、JIT架构。对大批量数据的访问和统计,效率更高。

d.读取很多列时,由于需要访问更多的文件,成本更高。例如查询明细。

e.需要REWRITE表时,不需要对全表操作,例如加字段有默认值,只是添加字段对应的那个文件。

3.列表选择使用场景:

OLAP的需求偏多,经常需要对数据进行统计时,选择列存。需要比较高的压缩比时,选择列存。如果用户有混合需求,可以采用分区表,例如按时间维度的需求分区,近期的数据明细查询多,那就使用行存,对历史的数据统计需求多那就使用列存。

查看表的存储结构:

pg_class.relstorage表示这个对象是什么存储,查询sql:

select relstorage, count(1) 数量 from pg_class group by relstorage;

Greenplum表存储模型选择

a – 行存储AO表

h – heap堆表、索引

x – 外部表(external table)

v – 视图

c – 列存储AO表

查询当前数据库有哪些AO表,查询sql:

select t2.nspname, t1.relname, t1.relstorage

from pg_class t1, pg_namespace t2

where t1.relnamespace = t2.oid

and relstorage in (‘c’, ‘a’);

Greenplum表存储模型选择

继续阅读