Postgres的TOAST技术(三)
29 | 851
4 | 29 | 851
4 | 29 | 1651
4 | 29 | 1651
4 | 29 | 2247
4 | 29 | 2247
(6 rows)
postgres=# insert into t_kenyon select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',10000);
INSERT 0 2
postgres=# select pg_relation_size(121174);
pg_relation_size
------------------
8192
(1 row)
postgres=# select pg_relation_size(121177);
pg_relation_size
------------------
16384
(1 row)
postgres=# insert into t_kenyon select generate_series(7,8),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',20000);
INSERT 0 2
postgres=# select id,pg_column_size(id),pg_column_size(vname),pg_column_size(remark) from t_kenyon;
id | pg_column_size | pg_column_size | pg_column_size
----+----------------+----------------+----------------
1 | 4 | 29 | 851
2 | 4 | 29 | 851
3 | 4 | 29 | 1651
4 | 4 | 29 | 1651
5 | 4 | 29 | 2247
6 | 4 | 29 | 2247
7 | 4 | 29 | 8056
8 | 4 | 29 | 8056
(8 rows)
postgres=# select pg_relation_size(121174);
pg_relation_size
------------------
8192
(1 row)
postgres=# select pg_relation_size(121177);
pg_relation_size
------------------
24576
(1 row)
可以看到后插入的数据随着字段内容的增多,toast段一直在变大。这个和
Oracle存储的大字段内容比较像,Oracle存储Blob类的数据时也是指定另外的segment来存储,而不是在原表中存储,当然可以设置enable storage in row来指定表中存储,所以Oracle里的表异常大时一般不是水位线过高就是表字段里存了大数据类型了。
四、TOAST的优缺点
1.可以存储超长超大字段,避免之前不能直接存储的限制
2.物理上与普通表是分离的,检索查询时不检索到该字段会极大地加快速度
3.更新普通表时,该表的Toast数据没有被更新时,不用去更新Toast表
Toast的劣势:
1.对大字段的索引创建是一个问题,有可能会失败,其实通常也不建议在大字段上创建,全文检索倒是一个解决方案。
2.大字段的更新会有点慢
五、其他
Toast的源码:
postgresql-9.2.3/src/backend/access/heap/tuptoaster.c
postgresql-9.2.3/src/backend/catalog/toasting.c