简介
在PostgreSQL中,页面的大小是固定的(通常是8k),而PostgreSQL不允许数据的分页存储,因此当存储一些大字段时,大字段通常会被压缩或者切片称为多行,存到的系统表 (toast)中。
可变类型数据在表中的存储
在可变长度类型中,表中前4个字节(32bit)称为长度字,后边的内容为指针或者数据的实际内容。
toast的长度最多1GB
可变类型的数据在表中的存储:
数据的指针组成:
- 数据的未压缩的大小
- 数据的实际存储大小
- 对应的toast表的oid
- toast表中的chunk_id
toast表
当一个表中的数据是可变长度时,系统会自动建一个关联的toast表,并在pg_class.reltoastrelid表中存储对应的关系。真实的数据时被分散到chunk块中进行存储的。在toast表每行都代表一个chunk块,chunk的大小是分页大小的1/4(默认2KB),包含以下内容:
- chunk_id:唯一标识
- chunk_seq:该chunk块在整体数据中的排序
- chunk_data :实际存储的内容
toast的策略及使用
4种toast策略:
策略 | 说明 |
---|---|
PLAIN | 避免压缩和行外存储。只有那些不需要 TOAST 策略就能存放的数据类型允许选择(例如 int 类型),而对于 text 这类要求存储长度超过页大小的类型,是不允许采用此策略的。 |
MAIN | 允许压缩,但不许行外存储。不过实际上,为了保证过大数据的存储,行外存储在其它方式(例如压缩)都无法满足需求的情况下,作为最后手段还是会被启动。因此理解为尽量不使用行外存储更贴切。 |
EXTENDED | 允许行外存储和压缩。一般会先压缩,如果还是太大,就会行外存储 |
EXTERNA | 允许行外存储,但不许压缩。类似字符串这种会对数据的一部分进行操作的字段,采用此策略可能获得更高的性能,因为不需要读取出整行数据再解压。 |
ALTER TABLE [表名] ALTER [字段名] SET STORAGE [策略名];
# 修改blog表中content内容的toast策略
ALTER TABLE blog ALTER content SET STORAGE EXTERNA ;
tip(关于压缩):
- 在chunk块数据在快接近其最大大小时(2040),数据才会被压缩
在11版本后,可以手动修改启动压缩的值
ALTER TABLE [表名] SET {toast_tuple_target=128};