POSTGRESQL 的TOAST 功能是POSTGRESQL 本身提供对于可变长大字段的管理的方式. 讲此方面的的文章也是比较多的. 这里想提及的是,从TOAST 功能中对数据库系统设计的一种新的认识和领会.
后面就通过提问和回答的方式来讲内容展开
1 为什么POSTGRESQL 要有TOAST 方式的存储数据
答: POSTGRESQL 默认数据存储的页的大小是8KB, 但我们不能保证存储数据的信息的大小,例如我们不能控制一行的大小,会让页不分割,但是POSTGRESQL的PAGE 是不支持页面分割的,跨页存储的. 所以TOAST 是一种防止一行的数据比较大,引起页的分割或跨页存储.
同时这样的设计也保证了,小的数据存储能在一个页面中,在提取到内存中的数量尽量的行数是多的,页面是少的,提高效率.
2 使用TOAST 到底有什么好处?
任何一项技术都有 BAD AND GOOD 的两面性, TOAST 功能本身是根据数据的特性来进行展现的例如我们都有一个概念, 就是大段的字符被查询的可能性比较小,并且这样的字段被更新的可能性也比较小. TOAST 功能也是本着这样的想法来实现,将经常查询的小字段存储在主页面内, 将超过2KB 以上的字段存储在其他的页面内,并且将信息分割,保存在外部的页面内. 这样的好处很自然,加速了常见的字段的查询,降低的不常用的字段加载到内存中. 这对整体的数据查询的速度和性能都是有保证的.
同时索引等建立,也都和一般的长字段无关,都是和我们的短字段有关的,从而提取数据的时候也不会和大字段有关,保证了系统的查询性能.
3 PostgreSQL的 TOAST 灵活性怎么样?
PostgreSQL 的灵活性, POSTGRESQL 的TOAST 功能本身并不是所有的字段都是要使用TOAST 来存储的,只有超过设定大小的字段才能进行数据的存储的TOAST 话. 实际上是可以调整两个值来控制本身 TOAST 的大小 TOAST_TUPLE_THRESHOLD 当超过这个默认值为2KB 的情况下,启动相关的数据压缩和字段迁移的过程, 当进行操作后,直到字段的值低于TOAST_TUPLE_TARGET默认2KB 后相关的TOAST的功能才停止. 并且这个值是可以进行调整的,例如
调整变大或者变小,对系统的性能都是有相关影响的.
如果这个表大部分都是大字段,那这个值可以稍微的调整的大一些,如果这些字段是要经常查询的情况下.
4
TOAST 的不利点:
和其他的数据库一样,POSTGRESQL 也不应该存储特别大的字段,尽量减少这些字段的存储,对数据库的性能是有提升和保护的.并且通过关联的方式进行访问本身的访问速度上也是有问题,并且如果访问,索引的问题也比较不容易解决.
下面是一个POSTGRESQL 关于TOAST 的插件,方便查看相关的信息
在插入相关TOAST插件后, 我们生成相关的测试数据,图中可以展示TOAST相关的详细信息
代码语言:javascript复制CREATE TABLE t (
a text,
b text
);
INSERT INTO t VALUES ('null', NULL);
INSERT INTO t VALUES ('default', 'default');
ALTER TABLE t ALTER COLUMN b SET STORAGE EXTERNAL;
INSERT INTO t VALUES ('external-10', 'external'); -- inline
INSERT INTO t VALUES ('external-10000', repeat('1',10000));
INSERT INTO t VALUES ('external-1000000', repeat('2',1000000));
ALTER TABLE t ALTER COLUMN b SET STORAGE EXTENDED;
INSERT INTO t VALUES ('extended-10', 'extended'); -- inline
INSERT INTO t VALUES ('extended-10000', repeat('3',10000));
INSERT INTO t VALUES ('extended-1000000', repeat('4',1000000));
SELECT a, length(b), pg_column_size(b), pg_toastinfo(b), pg_toastpointer(b) FROM t;
- null for NULLs
- ordinary for non-varlena datatypes
- short inline varlena for varlena values up to 126 bytes (1 byte header)
- long inline varlena, (un)compressed for varlena values up to 1GiB (4 bytes header)
- toasted varlena, (un)compressed for varlena values up to 1GiB stored in TOAST tables
这个插件提供了两个函数 pg_toastinfo 和 pg_toastpointer
实际上TOAST TABLE 存储策略可以配合实际实体表中的字段性质和表的业务性质和实际存储的性质来决定。
1 plain 表不使用TOAST 技术
2 extended 允许使用TOAST 技术, 先尝试压缩,然后在使用数据外部存储
3 external 允许使用TOAST技术,数据存储在外部, 但不使用压缩技术
4 Main 使用压缩技术来进行数据的存储,但不在外部存储数据
实际上针对toast技术,默认的值是extended 但如果想使用更高性能来让系统运行的更快应该使用external技术。
要查看当前表使用哪种存储技术 d 表名的方法来查看相关表到底使用哪种存储技术
说道TOAST的优势,从上面的内容中可以感受到TOAST 存储技术的额灵活性,可以根据字段的逻辑特性来,设置这个字段到底是不是需要压缩,是不是需要扩展,另外还可以调整某些阈值,让TOAST 技术不再默认的 2K 开始,或者延迟,提高存储的压缩率 或者 提高读取数据的性能。所以TOAST 在灵活性方面是其他数据库无法提供的一个重要的优势。