postgres=# create table toast_t(id int,vname varchar(48),remark text);
CREATE TABLE
postgres=# select relname,oid from pg_class where relname = 'toast_t';
relname | oid
---------+-------
toast_t | 16817
(1 row)
postgres=# select relname,reltoastrelid from pg_class where relname = 'toast_t';
relname | reltoastrelid
---------+---------------
toast_t | 16820
(1 row)
postgres=# select relname from pg_class where oid = '16820';
relname
----------------
pg_toast_16817
(1 row)
postgres=# --插入数据,此时remark列值长度小于2KB,所以不会触发toast存储
postgres=# insert into toast_t select generate_series(1,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',2000);
INSERT 0 4
postgres=# --查看表中列值大小
postgres=# select pg_column_size(id),pg_column_size(vname),pg_column_size(remark) from toast_t limit 10;
pg_column_size | pg_column_size | pg_column_size
----------------+----------------+----------------
4 | 29 | 851
4 | 29 | 851
4 | 29 | 851
4 | 29 | 851
(4 rows)
postgres=# --查看基础表和 Toast 的大小
postgres=# select pg_size_pretty(pg_relation_size('toast_t'));
pg_size_pretty
----------------
8192 bytes
(1 row)
postgres=# --查看toast表尺寸
select pg_size_pretty(pg_relation_size('16820'));
pg_size_pretty
----------------
0 bytes
(1 row)
postgres=# --此时remark列值长度小于2KB,所以不会触发toast存储
postgres=# --remark列值超过 2kb 左右时触发了toast存储方式
postgres=# insert into toast_t select generate_series(3,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',5500);
INSERT 0 2
postgres=# select pg_size_pretty(pg_relation_size('16820'));
pg_size_pretty
----------------
8192 bytes
(1 row)
postgres=# --查看各列的数据变化,说明在列尺寸超过2k的时候就会把数据存放到toast表中
postgres=# select pg_column_size(id),pg_column_size(vname),pg_column_size(remark) from toast_t;
pg_column_size | pg_column_size | pg_column_size
----------------+----------------+----------------
4 | 29 | 851
4 | 29 | 851
4 | 29 | 851
4 | 29 | 851
4 | 29 | 2247
4 | 29 | 2247
(6 rows)
postgres=# --继续插入更多的数据
postgres=# insert into toast_t select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',10000);
INSERT 0 2
postgres=# --查看toast表大小
postgres=# select pg_size_pretty(pg_relation_size('16820'));
pg_size_pretty
----------------
16 kB
(1 row)
postgres=# --继续插入更多的数据,20000
postgres=# insert into toast_t select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',20000);
INSERT 0 2
postgres=# --查看toast表大小
postgres=# select pg_size_pretty(pg_relation_size('16820'));
pg_size_pretty
----------------
32 kB
(1 row)
postgres=# --可以看到后插入的数据随着字段内容的增多,toast 段一直在变大。基础表的大小没有变化。这个和 Oracle 存储的大字段内容比较像,Oracle 存储 Blob和clob 类的数据时也是指定另外的 segment 来存储,而不是在原表中存储,当然可以设置 enable storage in row 来指定表中存储