greenplum列存

2023-03-07 00:00:00 查询 数据 子句 指令 压缩

Greenplum既支持行存储,也支持列存储。

行存储优劣分析

Greenplum行存储(堆表)的优势

数据顺序写入BLOCK中,持续写入的情况下,一条记录命中在一个块中,IO开销相对比较小,速度较快。

查询多个字段时,因为记录在一个块中命中,速度较快。

Greenplum行存储(堆表)的劣势

查询少量字段时,也要访问整条记录,造成一定的IO浪费。

行存储的压缩比有限。

行存储适合什么应用场景

行存储适合非常典型的OLTP应用场景。

列存储优劣分析

Greenplum列存储的优势

数据按列存储,压缩比可以做到很高。

当查询少量字段时,扫描的块更少,可以节约IO还能提升效率。

Greenplum列存储的劣势

因为是按列存储的,当需要查询大量字段时,或者查询的记录数偏少时,会造成离散IO较多。

例如查询1条记录的20个列,行存储可能只需要扫描1个块,而列存储至少需要扫描20个块。

由于IO的放大,列存储不适合OLTP的场景,如有大量的更新,查询操作。

列存储适合什么应用场景

列存储适合非常典型的OLAP应用场景,按列做较大范围的聚合分析,或者JOIN分析。

列存和行存的选择

在为一个表决定存储方向模型时,请考虑下列需求:
• 表数据的更新。如果用户会频繁地装载和更新表数据,请选择一个面向行的堆表。面向列的表存储只能用于追加优化表。
• 频繁的INSERT。如果频繁地向表中插入行,请考虑面向行的模型。列存表并未对写操作优化,因为一行的列值必须被写到磁盘上的不同位置。
• 查询中要求的列数。 如果在查询的SELECT列表或者WHERE子句中常常要求所有或者大部分列,请考虑面向行的模型。面向列的表适合的情况是,查询会聚集一个单一列中的很多值且WHERE或者HAVING谓词也在该聚集列上。例如:

SELECT SUM(salary)...
SELECT AVG(salary)... WHERE salary > 10000

另一种适合面向列的情况是WHERE谓词在一个单一列上并且返回相对较少的行。例如:

SELECT salary, dept ... WHERE state='CA'

• 表中的列数。 在同时要求很多列或者表的行尺寸相对较小时,面向行的存储会更有效。对于具有很多列的表且查询中访问这些列的一个小子集时,面向列的表能够提供更好的查询性能。
• 压缩。 列数据具有相同的数据类型,因此在列存数据上支持存储尺寸优化,但在行存数据上则不支持。例如,很多压缩方案使用临近数据的相似性来进行压缩。不过,临近压缩做得越好,随机访问就会越困难,因为必须解压数据才能读取它们。

创建一个面向列的表
CREATE TABLE命令的WITH子句指定表的存储选项。默认是面向行的堆表。使用面向列的存储的表必须是追加优化表。例如,要创建一个列存表:

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

建表时,在with(storage parameter)中指定:

或者在分区或子分区的with(storage parameter)中指定。

使用压缩(只适用于追加优化表)

相关文章