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

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介:

背景

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

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 加快速度。

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

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

目录
相关文章
|
Ubuntu Unix Linux
Linux系统之rename命令的基本使用
Linux系统之rename命令的基本使用
735 41
vscode 向下复制当前行功能快捷键 设置成Ctrl + D
vscode 向下复制当前行功能快捷键 设置成Ctrl + D
2138 0
|
存储 SQL 数据挖掘
深入理解 Flink 中的 State
Flink 的 State(状态)是其四大核心之一,为流处理和批处理任务提供强大支持。本文深入探讨 Flink 中的状态管理,涵盖 State 在 HDFS 中的存储格式、存在形式(如 ValueState、ListState 等)、使用方法、过期时间 TTL 和清除策略,并介绍 Table API 和 SQL 模块中的状态管理。通过实际案例,帮助读者理解如何在电商订单处理、实时日志统计等场景中有效利用状态管理功能。
1317 16
|
Oracle 关系型数据库 数据库
【赵渝强老师】Oracle的参数文件与告警日志文件
本文介绍了Oracle数据库的参数文件和告警日志文件。参数文件分为初始化参数文件(PFile)和服务器端参数文件(SPFile),在数据库启动时读取并分配资源。告警日志文件记录了数据库的重要活动、错误和警告信息,帮助诊断问题。文中还提供了相关视频讲解和示例代码。
337 1
|
敏捷开发 存储 数据管理
自动化测试框架设计:从理论到实践
【7月更文挑战第13天】本文将深入探讨自动化测试框架的设计原理与实现方法。通过分析自动化测试的必要性和框架设计的基本原则,结合具体案例,展示如何从零开始构建一个高效、可维护的自动化测试系统。文章不仅涵盖框架的结构设计,还包括最佳实践和常见问题的解决策略,为读者提供一套完整的解决方案和实操指南。
|
Java DataX 开发工具
datax-elasticsearch 同步踩坑记录
为了用datax同步es数据到其他地方,踩了不少坑.记录一下.
1154 0
|
关系型数据库
PostgreSQL 百亿级数据范围查询, 分组排序窗口取值 极致优化 case
本文将对一个任意范围按ID分组查出每个ID对应的最新记录的CASE做一个极致的优化体验。优化后性能维持在可控范围内,任意数据量,毫秒级返回,性能平稳可控。比优化前性能提升1万倍。 CASE如下: 有一张数据表,结构: CREATE TABLE target_position
17297 0
|
SQL 关系型数据库 数据库
PostgreSQL 如何潇洒的处理每天上百TB的数据增量
本文主要介绍并测试一下PostgreSQL 在中高端x86服务器上的数据插入速度,帮助企业用户了解PostgreSQL在这种纯插入场景的性能。(例如运营商网关数据,金融行业数据,产生量大,并且要求快速插入大数据库中持久化保存。) 测试结果写在前面:每32K的block存储89条记录, 每条记录约3
40794 131
|
SQL Kubernetes 安全
国产数据库-技术特性-CloudberryDB
Cloudberrydb基于gpdb,支持PG14内核,有很多GP目前不支持的优秀特性
888 0
|
存储 Ubuntu 安全
经典Ubuntu20.04版本U盘安装双系统教程
Ubuntu 建立在Debian的架构和基础架构之上,包括 Linux 服务器、桌面、物联以及云操作系统版本。最近项目需求换成linux的,入手ubuntu桌面比较简洁美观并且作为生产系统生态良好,开始了着手查找安装Ubuntu双系统的方法和视频,安装有两种:
2242 0
经典Ubuntu20.04版本U盘安装双系统教程