Postgresql TOAST「终于解决」

Postgresql TOAST「终于解决」Postgresql TOAST TOAST (The Oversized-Attribute Storage Technique) 超尺寸字段存储技术。就是说超长字段在Postgres的一个存储方…

Postgresql TOAST

Postgresql TOAST

TOAST (The Oversized-Attribute Storage Technique) 超尺寸字段存储技术。就是说超长字段在Postgres的一个存储方式。

WHY?

PostgreSQL page大小是固定的(通常为8KB),且不允许tuples跨多个page存储。因此不能存储非常大的字段值。为了克服这个限制,大字段值需要压缩甚至分割成多个物理行进行存储,这就是TOAST技术。TOAST对用户来说是透明的。

存储方式

Out-of-line, on-disk TOAST storage 行外磁盘存储

  • 当表中字段任何一个有Toast,那这个表都会有这一个相关联的Toast表,OID被存储在pg_class.reltoastrelid里面。Out-of-line values(可能是压缩后的,如果使用了压缩)将会被分割成chunks,每个chunk大小为toast_max_chunk_size(缺省是2Kb),每个chunk作为单独的一行存储在TOAST表中。
  • 相比较普通表(MAIN TABLE),TOAST有额外的三个字段(chunk_id,chunk_seq,chunk_data),有唯一索引在chunk_id和hunk_seq上提供快速查询。
chunk_id :标识TOASTed值的OID字段
chunk_seq :chunk的序列号,与chunk_id的组合唯一索引可以加速访问
chunk_data :存储TOAST的实际数据

代码100分

  • 当存储的行数据超过toast_tuple_threshold值(通常是2kB),就会触发toast存储,这时toast将会压缩或者移动超出的字段值直到行数据比toast_tuple_targer值小(这个值通常也是2KB)。所以基础表上可能只存了20%的数据

Toast有识别4种不同可存储toast的策略:

代码100分# plain避免压缩或行外存储
PLAIN prevents either compression or out-of-line storage; furthermore it disables use of single-byte headers for varlena types. This is the only possible strategy for columns of non-TOAST-able data types
# extended允许压缩和行外存储(默认toast存储)
EXTENDED allows both compression and out-of-line storage. This is the default for most TOASTable data types. Compression will be attempted first, then out-of-line storage if the row is still too big
# external允许行外但不允许压缩
EXTERNAL allows out-of-line storage but not compression. Use of EXTERNAL will make substring operations on wide text and bytea columns faster(at the penalty of increased storage space) because these operations are optimized to fetch only the required parts of the out-of-line value when it is not compressed
# main允许压缩但不允许行外存储
MAIN allows compression but not out-of-line storage. (Actually, out-of-line storage will still be performed for such columns, but only as a last resort when there is no other way to make the row small enough to fit on a page

上述压缩采用的是LZ compression技术。 可以通过 ALTER TABLE … SET STORAGE更改字段的存储策略

查看TOAST存储

查看TOAST存储

CREATE TABLE test_toast(
    id int,
    name text,
    age int,
    create_time timestamp without time zone);

INSERT INTO test_toast SELECT generate_series(1,10000),md5(random()::text),
((random()*100)::integer),clock_timestamp();

d+ test_toast;
Table "test.test_toast"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-------------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
id | integer | | | | plain | |
name | text | | | | extended | |
age | integer | | | | plain | |
create_time | timestamp without time zone | | | | plain | |

 select relname,relfilenode,reltoastrelid from pg_class where relname="test_toast";
relname | relfilenode | reltoastrelid
------------+-------------+---------------
test_toast | 102417 | 102420
(1 row)
注意:TOAST表名,可通过以下方式查看
 ! oid2name -d postgres -f 102420
From database "postgres":
Filenode Table Name
---------------------------
102420 pg_toast_102417

含有TOAST表的空间大小计算!

代码100分如果表中有某些字段使用TOAST进行存储,那么,通过普通的pg_relation_size("表名")查询不到TOAST字段所占用的空间。如果要查询TOAST字段所占用的空间,可以先查询出TOAST字段对应的OID,再通过pg_relation_size(OID)的方式查询出TOAST字段所占用的空间。


select pg_size_pretty(pg_relation_size("test_toast","main"));
select pg_size_pretty(pg_relation_size(102420));

增加字段大小,产生TOAST存储
update test_toast set name=name||name where id=1;

postgres=> select pg_size_pretty(pg_relation_size(102417));
pg_size_pretty
----------------
832 kB
(1 row)
postgres=> select pg_size_pretty(pg_relation_size(102420));
pg_size_pretty
----------------
3072 kB
(1 row)
postgres=> select pg_size_pretty(pg_table_size("test_toast"));
pg_size_pretty
----------------
4016 kB
(1 row)
使用pg_table_size查出的结果是包括TOAST字段所占用的空间的。
注意:物理文件空间大小查询参考《Cluster database and table》

TOAST的优缺点

Toast的优点

  • 可以存储超长超大字段,避免之前不能直接存储的限制
  • 物理上与普通表是分离的,检索查询时不检索到该字段会极大地加快速度
  • 更新普通表时,该表的Toast数据没有被更新时,不用去更新Toast表

Toast的劣势:

  • 对大字段的索引创建是一个问题,有可能会失败,其实通常也不建议在大字段上创建,全文检索倒是一个解决方案。
  • 大字段的更新会有点慢,其它DB也存在,通病

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/8783.html

(0)
上一篇 2023-02-22
下一篇 2023-02-22

相关推荐

  • MySQL 事务 异常 事务隔离的级别 – G

    MySQL 事务 异常 事务隔离的级别 – GMySQL 事务 异常 事务隔离的级别 事务 在你操作数据库的同时,有可能其他用户还会不断地对数据进行增删改查操作。为了避免并行进行时出现混乱,就产生了“事务”。事务就是要保证一组数据库操作,要么全部

    2023-03-16
    162
  • 使用Python编写IMX Star固件升级工具

    使用Python编写IMX Star固件升级工具IMX Star是一款应用广泛的嵌入式系统芯片,其广泛应用于数码相机、智能摄像头等领域。为了满足客户的需求,芯片厂商需要不断升级其固件,并提供升级工具。本文将介绍如何使用Python开发一款IMX Star固件升级工具。

    2024-03-14
    75
  • 在Linux中安装Vim编辑器

    在Linux中安装Vim编辑器在操作Linux系统时,文本编辑器是一个极其重要的工具。在Linux系统中,Vim是一款广泛使用的文本编辑器,其广泛的应用性和强大的功能让它成为许多开发者的必选编辑器。

    2024-05-31
    57
  • 巨杉数据库公司怎么样_gartner数据库

    巨杉数据库公司怎么样_gartner数据库本文由巨杉数据库北美实验室资深数据库架构师撰写,主要介绍巨杉数据库的并发malloc实现与架构设计。原文为英文撰写,我们提供了中文译本在英文之后。 SequoiaDB Concurrent mall…

    2023-01-28
    132
  • windows下MySQL解压版安装[通俗易懂]

    windows下MySQL解压版安装[通俗易懂]MySQL的安装 一、前期准备 获取MySQL解压版安装包(本文使用的是 【mysql-5.7.28-winx64.zip】版本) 获取方式: 通过官网下载,官方下载地址:“https://dev.m

    2022-12-27
    148
  • 时序数据库 Apache-IoTDB 源码解析之文件格式简介(三)

    时序数据库 Apache-IoTDB 源码解析之文件格式简介(三)上一章聊到在车联网或物联网中对数据库的需求,以及 IoTDB 的整体架构,详情请见: 时序数据库 Apache-IoTDB 源码解析之系统架构(二) 打一波广告,欢迎大家访问IoTDB 仓库,求一波…

    2023-01-27
    149
  • 实用教程丨使用K3s和MySQL运行Rancher 2.4[通俗易懂]

    实用教程丨使用K3s和MySQL运行Rancher 2.4[通俗易懂]本文转自Rancher Labs 简 介 本文将介绍在高可用K3s Kubernetes集群上安装Rancher 2.4的过程并针对MySQL利用Microsoft Azure数据库的优势,该数据库消

    2023-03-06
    141
  • Python字典.items()方法,快速获取键值对!

    Python字典.items()方法,快速获取键值对!Python字典是一种键-值对数据结构,其中每个键都有对应的值。通常情况下,字典的键是唯一的,而值则可以是任何数据类型。Python中的字典类提供了许多实用的方法,其中包括.items()方法,该方法可以让我们快速获取字典的键值对。.items()方法返回一个代表字典中所有键值对的列表,其中每个元素本身就是一个由键值组成的元组。以下是.items()方法的基本语法:

    2024-02-26
    102

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注