openGauss你计算的表大小,有包含toast表么?

news2024/11/30 20:35:39

openGauss你计算的表大小,有包含toast表么?

最近有一个同事问我说“openGauss中pg_relation_size函数在计算表的大小时是否包含了大字段的大小?”,经过思考后,自己觉得表的大小是不包含大字段的大小的,然后通过查看官网的文档说明,该函数含义为指定OID代表的表或者索引所使用的磁盘空间。如果只单独看这条定义,那么还是不清楚是否包含toast表,但是如果你看了数据库对象的其他函数,结合其他函数的解释应该可以得出结论在这里是不包含toast表的大小。即使知道结果了,还是想通过实际操作验证一下openGauss的pg_relation_size函数在计算表大小时未包含toast表大小。关于toast机制在这里就不做详细介绍,有兴趣的同学,可以自行查看相关资料。

准备测试用例

创建测试用例表

create table tbl_blog (id serial primary key,author varchar(50),title varchar(200),content text);

查看表结构

testdb=> \d+ tbl_blog
                                                      Table "test.tbl_blog"
 Column  |          Type          |                       Modifiers                       | Storage  | Stats target | Description
---------+------------------------+-------------------------------------------------------+----------+--------------+-------------
 id      | integer                | not null default nextval('tbl_blog_id_seq'::regclass) | plain    |              |
 author  | character varying(50)  |                                                       | extended |              |
 title   | character varying(200) |                                                       | extended |              |
 content | text                   |                                                       | extended |              |
Indexes:
    "tbl_blog_pkey" PRIMARY KEY, btree (id) TABLESPACE pg_default
Has OIDs: no
Options: orientation=row, compression=no

在这里我们可以看到author、title、content的storage列的值为extended,这是大多数toast数据类型的默认设置,表示允许行外存储和压缩,一般会先压缩,如果还是太大,就会行外存储。这里行外存储其实就是指,当行的记录的长度大于了TOAST_TUPLE_THRESHOLD(值为2KB)时,会触发TOAST,把大字段的列数据存储到TOAST表中。

查看tbl_blog关联的toast表的oid

testdb=> select oid,relname,reltoastrelid from pg_class where relname='tbl_blog';
  oid  | relname  | reltoastrelid
-------+----------+---------------
 24608 | tbl_blog |         24612
(1 row)

查询关联的toast表的表名及表数据

--查看toast表名
testdb=# select relname from pg_class where oid = 24612;
    relname
----------------
 pg_toast_24608
(1 row)

在这里可以看到TOAST表名,其实就是pg_toast+表的oid。

查看toast表的信息

testdb=# select tableoid ,* from pg_toast.pg_toast_24608;
 chunk_id | chunk_seq | chunk_data
----------+-----------+------------
(0 rows)
--查看TOAST表结构
testdb=> \d+ pg_toast.pg_toast_24608
TOAST table "pg_toast.pg_toast_24608"
   Column   |  Type   | Storage
------------+---------+---------
 chunk_id   | oid     | plain
 chunk_seq  | integer | plain
 chunk_data | bytea   | 

这里简单的对toast表的字段说明一下

chunk_id:普通表通过TOAST pointer关联到一个被TOAST的列

chunk_seq:同一个chunk_id如果大于TOAST_MAX_CHUNK_SIZE,将被切片存储。这里存储切片后的序号

chunk_data:真实的数据,但是在这里展示的都是二进制值

模拟数据验证

content字段插入少许值

执行命令插入数据

insert into tbl_blog(author,title,content) values('墨竹','推荐Postgresql中一些好用的psql命令','psql客户端工具应该是dba非常频繁使用的的工具。');

查看表大小和toast表的大小

testdb=# select pg_relation_size(oid) as tb_size,pg_relation_size(reltoastrelid) as toast_size from pg_class where relname='tbl_blog';
 tb_size | toast_size
---------+------------
    8192 |          0
(1 row)
--同样在toast表的数据仍然为空
testdb=# select * from pg_toast.pg_toast_24608;
 chunk_id | chunk_seq | chunk_data
----------+-----------+------------
(0 rows)

在上面查询结果可以看到当插入的值比较小时,在toast表未查询到数据。然后我们再查看content列的长度,为46字节。

testdb=> select pg_column_size(id),pg_column_size(author),pg_column_size(title),pg_column_size(content) from tbl_blog;
 pg_column_size | pg_column_size | pg_column_size | pg_column_size
----------------+----------------+----------------+----------------
              4 |              5 |             35 |             46
(1 row)

content字段插入大量值

执行命令插入数据,在这里省略了大量的数据,自行测试的时候,找一些数据就行。

insert into tbl_blog(author,title,content) values('墨竹','推荐Postgresql中一些好用的psql命令','E.1.1. Overview 
PostgreSQL 17 contains many new features and enhancements, including:
....省略大量文字
Add worker type column to pg_stat_subscription (Peter Smith) §');

查看表大小和toast表的大小

testdb=# select pg_relation_size(oid) as tb_size,pg_relation_size(reltoastrelid) as toast_size from pg_class where relname='tbl_blog';
 tb_size | toast_size
---------+------------
    8192 |       8192
(1 row)
--在这里由于chunk_data太大不方便展示,就截取了一部分
testdb=> select chunk_id,chunk_seq,substring(chunk_data,0,20) from pg_toast.pg_toast_24608;
 chunk_id | chunk_seq |                substring
----------+-----------+------------------------------------------
    24618 |         0 | \x3a35000000452e312e312e204f007665727669
    24618 |         1 | \x219b6c75652066021387926b946a114457696e
    24618 |         2 | \x015620ce63113712450475697383ae4380606f
    24618 |         3 | \x2204a824e26d616e69e47075443a6f66710973
(4 rows)

当再次插入数据时,表的大小未变化,但是toast表的变为了8KB,说明这个时候已经出发toast机制,将content列的数据存储到toast表。当查看toast表中的数据时,发现已经有数据并且由于插入的太大,对插入的数据进行了切分。最后再来查看一下列的长度,为7286字节,确实是需要切分的。

testdb=# select pg_column_size(id),pg_column_size(author),pg_column_size(title),pg_column_size(content) from tbl_blog;
 pg_column_size | pg_column_size | pg_column_size | pg_column_size
----------------+----------------+----------------+----------------
              4 |              7 |             45 |             65
              4 |              7 |             45 |           7286
(2 rows)

再次插入数据

再次把第2次的数据重新插入一次

insert into tbl_blog(author,title,content) select author,title,content from tbl_blog where id = 2;

查看表大小和toast表的大小

testdb=> select pg_relation_size(oid) as tb_size,pg_relation_size(reltoastrelid) as toast_size from pg_class where relname='tbl_blog';
 tb_size | toast_size
---------+------------
    8192 |      24576
(1 row)
--在这里由于chunk_data太大不方便展示,就截取了一部分
testdb=> select chunk_id,chunk_seq,substring(chunk_data,0,20) from pg_toast.pg_toast_24608;
 chunk_id | chunk_seq |                substring
----------+-----------+------------------------------------------
    24618 |         0 | \x3a35000000452e312e312e204f007665727669
    24618 |         1 | \x219b6c75652066021387926b946a114457696e
    24618 |         2 | \x015620ce63113712450475697383ae4380606f
    24618 |         3 | \x2204a824e26d616e69e47075443a6f66710973
    24620 |         0 | \x3a35000000452e312e312e204f007665727669
    24620 |         1 | \x219b6c75652066021387926b946a114457696e
    24620 |         2 | \x015620ce63113712450475697383ae4380606f
    24620 |         3 | \x2204a824e26d616e69e47075443a6f66710973
(8 rows)

当我们再次对content字段插入大量值时,发现表的大小未变化,但是toast表大小翻了3倍。

查看列的长度

testdb=>  select pg_column_size(id),pg_column_size(author),pg_column_size(title),pg_column_size(content) from tbl_blog;
 pg_column_size | pg_column_size | pg_column_size | pg_column_size
----------------+----------------+----------------+----------------
              4 |              5 |             35 |             46
              4 |              5 |             35 |           7286
              4 |              5 |             35 |           7286
(3 rows)

其实通过这三次的插入数据,观察pg_relation_size函数计算表的大小和toast表的大小,其中表的大小一直未变,toast表的大小从0->8192->24576,就可以判断出pg_relation_size函数计算表的大小时是不包含toast表的大小,如果你忽略这点的话,可能导致最终统计的数据不准确。

下面是计算数据库表/索引大小相关的函数。

pg_relation_size(oid)
描述:指定OID代表的表或者索引所使用的磁盘空间。

pg_indexes_size(regclass)
描述:附加到指定表的索引使用的总磁盘空间。

pg_table_size(regclass)
描述:指定的表使用的磁盘空间,不计索引(但是包含TOAST,自由空间映射和可见性映射)

pg_total_relation_size(regclass)
描述:指定的表使用的总磁盘空间,包括所有的索引和TOAST数据

总结

从这个测试实验中,我们就可以很清晰的知道,pg_relation_size函数只统计表对象的大小,未包含toast表大小,因此如果我们需要统计表大小,建议使用pg_total_relation_size函数更精确一点,该函数的统计包括了索引和toast表;另外如果你使用了pg_table_size来统计表大小,需要注意该统计不包含索引,可能需要使用pg_indexes_size来单独计算索引的大小。

参考
https://github.com/digoal/blog/blob/master/201103/20110329_01.md

本文作者:墨竹

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2250668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

跨境物流市场风云变幻,集运企业需精准决策以应对挑战

跨境物流市场,作为全球经济的重要纽带,正经历着前所未有的风云变幻。据最新数据显示,全球海运贸易在2023年实现了2.4%的增长,并预计在今年年底前将再增长2%。这一增长态势虽然积极,但背后却隐藏着诸多挑战与不确定性。…

2024年首届数证杯 初赛wp

“数证杯”电子数据取证分析大赛致力于成为全国第一大电子数据取证分析大赛,面向所有网络安全从业人员公开征集参赛选手。参赛选手根据所属行业报名参赛赛道,比赛设置冠军、亚军、季军奖。所涉及行业包括能源、金融、通信、取证、安全等企业以及各类司法…

电机瞬态分析基础(3):空间矢量

1. 空间矢量 空间矢量的概念在交流电机分析与控制中具有非常重要的作用。将各相的电压、电流、磁链等电磁量用空间矢量表达,可以使三相感应电机的动态方程表达更简洁,为电机的分析与控制带来方便,并有助于对交流电机的矢量控制、直接转矩控制…

C/C++绘制爱心

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C/…

LLM应用-prompt提示:RAG query重写、相似query生成 加强检索准确率

参考: https://zhuanlan.zhihu.com/p/719510286 1、query重写 你是一名AI助手,负责在RAG(知识库)系统中通过重构用户查询来提高检索效果。根据原始查询,将其重写得更具体、详细,以便更有可能检索到相关信…

MTK主板_小型联发科安卓主板_行业智能终端主板基于联发科方案

MTK安卓主板是一款小巧而高效的科技产品,其尺寸仅为43.4mm x 57.6mm。采用了先进的联发科12nm制程工艺,这款主板搭载四核或八核64位A53架构的CPU,主频高达2.0GHz,不但保证了出色的计算能力,还实现了超低功耗的特点。系…

递归---汉诺塔

问题描述 有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,要把所有盘子一个一个移动到柱子B上,并且每次移动,同一根柱子上都不能出现大盘子在小盘子上方,输出每次的移动。…

HTML飞舞的爱心(完整代码)

写在前面 HTML语言实现飞舞的爱心完整代码。 完整代码 <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>飞舞爱心</title><style>* {margin: 0;padding: 0;}html,body {overflow: hidd…

修改训练策略,无损提升性能

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月29日15点40分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文链接 点击开启你的论文编程之旅…

@bytemd/vue掘金markdown插件预览内容有误

vue项目使用bytemd/vue 来预览字符串格式的markdown内容&#xff0c;总会多出如图的一段代码&#xff0c; 请问有没有大佬知道为什么&#xff1f; 很急&#xff0c;求教&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;

Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:电影院后台管理系统(前后端源码 + 数据库 sql 脚本)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 项目介绍 2.0 用户登录功能 3.0 用户管理功能 4.0 影院管理功能 5.0 电影管理功能 6.0 影厅管理功能 7.0 电影排片管理功能 8.0 用户评论管理功能 9.0 用户购票功…

window.structuredClone 深拷贝

概述&#xff1a; structuredClone 是一种新的 JavaScript 原生方法&#xff0c;用于创建一个对象的深拷贝。与传统的浅拷贝方法&#xff08;如 Object.assign 或数组的 slice&#xff09;不同&#xff0c;structuredClone 可以递归地拷贝对象&#xff0c;包括其中的嵌套对象、…

java全栈day10--后端Web基础(基础知识)

引言&#xff1a;只要能通过浏览器访问的网站全是B/S架构&#xff0c;其中最常用的服务器就是Tomcat 在浏览器与服务器交互的时候采用的协议是HTTP协议 一、Tomcat服务器 1.1介绍 官网地址&#xff1a;Apache Tomcat - Welcome! 1.2基本使用(网上有安装教程&#xff0c;建议…

java:拆箱和装箱,缓存池概念简单介绍

1.基本数据类型及其包装类&#xff1a; 举例子&#xff1a; Integer i 10; //装箱int n i; //拆箱 概念&#xff1a; 装箱就是自动将基本数据类型转换为包装器类型&#xff1b; 拆箱就是自动将包装器类型转换为基本数据类型&#xff1b; public class Main {public s…

保持角色一致性!flux新模型redux用法(含模型与工作流)

​ 目录 redux模型是什么&#xff0c;能干啥&#xff1f; 用到的工具有哪些&#xff1f; 工具和模型文件在哪里下载&#xff1f; 整合包&#xff1a; 下载后需要分别放到指定目录&#xff1a; redux模型怎么用&#xff1f; 加载工作流 上传图片和输入提示词 生成结果…

通信原理实验:抽样定理实验

目录 一、实验目的和要求 二、实验内容和原理 实验器材 实验原理 三、实验步骤 (一)实验项目一:抽样信号观测及抽样定理验证 四、实验记录与处理 结论: 辅助学习资料: 五、实验结果及分析 一、实验目的和要求 了解抽样定理在通信系统中的重要性。掌握自然抽样及…

HarmonyOS NEXT应用开发,关于useNormalizedOHMUrl选项的坑

起因是这样的&#xff1a;我这库打包发布出问题了&#xff0c;这个有遇到的吗&#xff1f; 源码里面就没有 request .d.ts,这打包后哪来个这文件&#xff1f;且漏掉了其他文件。 猫哥csdn.yyz_1987 为啥我打包的har里面&#xff0c;只有接口&#xff0c;没有具体实现呢&#x…

Ubuntu Server 22.04.5 从零到一:详尽安装部署指南

文章目录 Ubuntu Server 22.04.5 从零到一&#xff1a;详尽安装部署指南一、部署环境二、安装系统2.1 安装2.1.1 选择安装方式2.1.2 选择语言2.1.3 选择不更新2.1.4 选择键盘标准2.1.5 选择安装版本2.1.6 设置网卡2.1.7 配置代理2.1.8 设置镜像源2.1.9 选择装系统的硬盘2.1.10 …

学成在线day07

视频处理 技术方案 掌握了xxl-job的分片广播调度方式&#xff0c;下边思考如何分布式去执行学成在线平台中的视频处理任务。 任务添加成功后&#xff0c;对于要处理的任务会添加到待处理任务表中&#xff0c;现在启动多个执行器实例去查询这些待处理任务&#xff0c;此时如何…

在国外,使用中国移动app办理停机保号

1.人在国内的时候&#xff0c;先使用手机下载中国移动app 以前网上营业厅是可以直接办理停机保号的&#xff0c;现在不可以了 2.人在国内的时候&#xff0c;确保自己的手机能够登录中国移动app 这个步骤保证回国前可以使用中国移动app复机 3.人在国内的时候&#xff0c;拨打…