1、什么是TOAST?


TOAST,全称是The Oversized-Attribute Storage Technique, 超大属性存储技术,顾名思义,就是Pg中超长字段在数据库中的存储方式。

主要用来应对物理数据行超过数据块(页)大小的场景


在PG中,页(或者叫block)是数据在文件存储中的基本单位,它的大小是固定的,并且只能在编译期指定,之后无法修改,默认的大小为8kb。同时PG不允许一行数据跨页存储。因此页大小就是行大小的硬上限,因此,数据库就无法直接存储很大的字段值,为了克服这一限制,Pg引入了TOAST技术,TOAST技术是采用压缩和切片的方式,使得行的大小变小。


注意:这一技术对用户来说是完全透明的,用户不需要关注这一技术实现。



2、怎么理解压缩和切片?


我们创建的每个表都有自己关联且唯一的TOAST表。当数据超过TOAST_TUPLE_THRESHOLD(默认2KB)时,Postgres将压缩数据,以适应2KB的缓冲区大小。如果对大列数据的压缩没有导致更小的块(<2KB),那么它将被拆分为更小的块,并存储在相关TOAST表中的多个物理行(行外存储)。每个原始字段值都被一个指针替换,根据这个指针可以找到行外存储的数据。




3、怎么查看与原始表相关的TOAST表?


select relname from pg_class where oid = (select reltoastrelid from pg_class where relname=’TABLE_NAME’)

通常表名为:pg_toast_$(OID),其中OID是toast表的OID,即原始表的reltoastrelid。

该表在pg_toast模式下,所以查询时我们需要使用:

select * from pg_toast.pg_toast_$(OID)



5、PG中表字段的TOAST策略?


PLAIN: 避免压缩和行外存储。

EXTENDED:允许压缩和行外存储。

EXTERNAL: 允许行外存储,但不允许压缩。

MAIN: 允许压缩,但不允许行外存储。



6、怎么查看表字段的TOAST策略?

\d+ tableName

=> \d+ test_table_name
                      Table "name_space.test_table_name"
Column |       Type        | Modifiers | Storage  | Stats target | Description
--------+-------------------+-----------+----------+--------------+-------------
 foo   | character(100000) |           | extended |              |

其中的Storage显示字段使用的TOAST策略。


7、怎么修改表字段的TOAST策略?

alter table test_blob alter column column_name set storage EXTENDED;


8、PG中所有数据类型都支持TOAST吗?

不是。只有特定的数据类型支持TOAST,因为因为有些字段类型是不会产生大字段数据的,没有必要为它们增加额外的开销。(比如int、boolean等)。另外,注意支持TOAST的数据类型必须是变长的


9、TOAST的优点是什么?

消除了当存储超长超大字段时,无法直接存储的限制。

TOAST表与原始表是分离的,当检索或者更新时不涉及该字段可以极大地加快操作速度。

https://mp.weixin.qq.com/s/dgX8i_dY8lgjGXMJdMrLcA