Greenplum行存与列存的选择以及转换方法

简介:

背景

数据在数据库中的存储形式多种多样,比较常见的如

1. PostgreSQL的堆表,以行的形式存储,(当变成字段压缩后的长度超过数据块的四分之一时,会以TOAST的形式存储到TOAST表)。

2. MySQL innodb则是以b+tree形式存储的。

  1. 在数据仓库产品中,如Greenplum,支持行存,也支持列存。

    还有很多存储格式,本文将讨论行存和列存应该如何选择呢?

行存储优劣分析

Greenplum行存储(堆表)的优势在哪里?

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

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

Greenplum行存储(堆表)的劣势在哪里?

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

行存储的压缩比有限。

行存储适合什么应用场景

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

列存储优劣分析

Greenplum列存储的优势在哪里?

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

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

Greenplum列存储的劣势在哪里?

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

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

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

列存储适合什么应用场景

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

如何设置表的存储格式

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

screenshot

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

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

screenshot

因此Greenplum的存储格式支持到了子分区这个级别,一张表(指父表)可以混合使用行存储与列存储。

如何转换表的存储格式

screenshot

screenshot

行列混合存储应用场景

例如用户如果有一张按时间分区的表,最近1个月的查询类似OLTP的请求,需要查询较多字段,而一个月以前的表则OLAP的需求更旺盛。

这种情况下,我们的需求是将老的分区转换为列存储,怎么做呢?

例子

创建分区表,选择行存储

create table t_digoal (id int, info text, crt_time timestamp) distributed by (id) partition by range(crt_time) (start (date '2016-08-01') inclusive end (date '2016-12-01') exclusive every (interval '1 day'));

查看分区定义

postgres=> select * from pg_partitions;
-[ RECORD 1 ]------------+----------------------------------------------------------------------------------------------------------------------------------------------
schemaname               | public
tablename                | t_digoal
partitionschemaname      | public
partitiontablename       | t_digoal_1_prt_1
partitionname            | 
parentpartitiontablename | 
parentpartitionname      | 
partitiontype            | range
partitionlevel           | 0
partitionrank            | 1
partitionposition        | 1
partitionlistvalues      | 
partitionrangestart      | '2016-08-01 00:00:00'::timestamp without time zone
partitionstartinclusive  | t
partitionrangeend        | '2016-08-02 00:00:00'::timestamp without time zone
partitionendinclusive    | f
partitioneveryclause     | '1 day'::interval
partitionisdefault       | f
partitionboundary        | START ('2016-08-01 00:00:00'::timestamp without time zone) END ('2016-08-02 00:00:00'::timestamp without time zone) EVERY ('1 day'::interval)
parenttablespace         | pg_default
partitiontablespace      | pg_default
-[ RECORD 2 ]------------+----------------------------------------------------------------------------------------------------------------------------------------------
schemaname               | public
tablename                | t_digoal
partitionschemaname      | public
partitiontablename       | t_digoal_1_prt_2
partitionname            | 
parentpartitiontablename | 
parentpartitionname      | 
partitiontype            | range
partitionlevel           | 0
partitionrank            | 2
partitionposition        | 2
partitionlistvalues      | 
partitionrangestart      | '2016-08-02 00:00:00'::timestamp without time zone
partitionstartinclusive  | t
partitionrangeend        | '2016-08-03 00:00:00'::timestamp without time zone
partitionendinclusive    | f
partitioneveryclause     | '1 day'::interval
partitionisdefault       | f
partitionboundary        | START ('2016-08-02 00:00:00'::timestamp without time zone) END ('2016-08-03 00:00:00'::timestamp without time zone) EVERY ('1 day'::interval)
parenttablespace         | pg_default
partitiontablespace      | pg_default

创建列存单表,用于交换分区

postgres=> create table t_digoal_col(id int, info text, crt_time timestamp) with (appendonly=true, ORIENTATION=column) distributed by (id);
CREATE TABLE

将历史分区数据插入列存储的交换分区

insert into t_digoal_col select * from t_digoal_1_prt_1;

指定对应的rank,交换分区

alter table t_digoal exchange partition for (rank(1)) with table t_digoal_col with validation;

可以使用 without validation 加快速度。

祝大家玩得开心,欢迎随时来 阿里云促膝长谈业务需求 ,恭候光临。

阿里云的小伙伴们加油,努力 做好内核与服务,打造最贴地气的云数据库 。

目录
相关文章
|
数据可视化 关系型数据库 MySQL
宝塔面板数据库迁移一种小技巧方式
要迁移数据,那么一般情况下两边服务器的mysql版本、配置应该保持一致 将变化的可能性尽可能减低,否则你不会预料到迁移过后会发生什么事.. 其实这个方法只是在恢复数据的时候一种小灵活的手法。主体逻辑还是没有变化的。
1533 114
宝塔面板数据库迁移一种小技巧方式
|
存储 关系型数据库 数据库
RDS:稳定、安全、开放的新一代云数据库服务
RDS是阿里云提供的新一代云数据库服务,具备稳定、安全、开放的特点。本次分享由阿里云智能集团和平安科技专家共同介绍,涵盖RDS年度产品发布与最佳实践、金融场景下关系型数据库的要求。重点内容包括RDS通用云盘、RDS On OSS、RDS Custom等技术创新,以及在成本控制、性能优化、业务连续性、数据安全等方面的解决方案。通过实际案例展示了RDS在不同行业的应用,如汇联易、莉莉丝游戏、中免日上等,帮助客户实现高效、低成本的数据库管理。
1505 116
|
存储 算法 关系型数据库
一个简单算法可以帮助物联网,金融 用户 节约98%的数据存储成本 (PostgreSQL,Greenplum帮你做到)
PostgreSQL简直是工业界和学术界的完美结合,怎么说呢?下面娓娓道来。前段时间为大家分享了物联网行业分析以及PostgreSQL 为物联网场景量身定制的特性介绍。https://yq.aliyun.com/articles/18034https://yq.aliyun.com/edu/les.
13233 110
|
Java 关系型数据库 MySQL
mybatis 字段与数据库关键字冲突了怎么办、mybatis for 循环查询输出、mybatis常用标签
mybatis 字段与数据库关键字冲突了怎么办 如update join_brand_hot set index = #{top} where id = #{id}
1246 120
|
数据采集 移动开发 算法
如何让机器读懂视频| 开发者必读(135期)
主要详细介绍了多模态在视频分类算法中的应用探索及视频分类算法中的层次化分类器的设计
1421 119
|
Web App开发 前端开发 算法
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
例如:12的全排列是12、21,123的全排列是123、132、213、231、312、321。依次类推:1234的全排列是……… 在123 的全排列中,我们使用3个盒子存放即将放进的数字,每当走到一个盒子前就把手中的数字放进去,手中的数字没了之后,再次返回,把盒子中的数字拿走,再次进行排列。
1405 136
|
SQL 数据格式 XML
Mybatis之动态SQL
样例包含了If,choose,where,set,foreach,bind. 基本覆盖了常见的动态SQL用法。
10260 118