PostgreSQL 列大小与表大小

Posted

技术标签:

【中文标题】PostgreSQL 列大小与表大小【英文标题】:PostgreSQL column size vs table size 【发布时间】:2022-01-24 00:48:00 【问题描述】:

我试图只获得一个表格大小,然后是每一行的大小。 在我使用时

SELECT pg_table_size(*mytable*) as DATA;

我得到 393216 个字节。

使用

SELECT (SUM(pg_column_size(t) - 24)) FROM *mytable* AS t;

(写在这里How to get each row size of a particular table in postgresql..?)

我得到 560669 字节。

560669 与 393216 字节 - 哪一个是真实的?

【问题讨论】:

目标是 - 获取每行的 REAL 值,然后获取所有行的 REAL 值。我需要访问这个.. TOAST 表是否包含数据? 我只能将“TOAST”视为架构 - 所以 toast 和 toast_temp 都是空的。 我说的是你可以通过SELECT reltoastrelid::regclass FROM pg_class WHERE relname = 'mytable';找到的表格 起床,我的错。是的,它是空的。 // 编辑:另一个错误。不是,我使用了包含模式的查询。没有架构 - 结果只有一行。 【参考方案1】:

来自https://www.postgresql.org/docs/14/functions-admin.html

pg_table_size - 计算指定表使用的磁盘空间, 不包括索引(但包括其 TOAST 表(如果有)、可用空间 地图和可见性地图)。

所以 pg_table_size 为您提供了 postgres 用于表的磁盘数量以及 postgres 保留的有关表的一些元数据(Visibility Map 和 Free Space Map)。 Deleting a row will not decrease this number(除非您执行 VACUUM FULL),因此我们不希望表使用的磁盘与每个可见行中的数据总和相匹配。相反,表使用的磁盘会更大。

pg_column_size - 显示用于存储任何个人的字节数 数据价值。如果直接应用于表列值,则反映 任何已完成的压缩。

所以这会返回磁盘上每一行的大小(包括存储在磁盘上的行头信息)。

我不确定您是否会认为行标题信息是“真实的”,但它确实会占用您的硬盘空间,因此这是否正确取决于您的用例。

使用我拥有的数据库中的示例表:

SELECT pg_table_size('users')
-- 3751936 <-- the size of my 'users' table on disk, including table meta-data
SELECT (SUM(pg_column_size(t.*))) FROM users AS t;
-- 3483028 <-- the total size on disk of the visible rows, including row "header" metadata.
SELECT (SUM(pg_column_size(t.*)-24)) FROM users AS t;
-- 3069412 <-- the size of the data in visible rows, excluding row "header" meta-data

我们希望这些查询中的每一个都返回不同的数字,并且每个查询都有不同的用途。

至于您发布的具体数字(pg_column_size 大于pg_table_size)我无法解释。

【讨论】:

我同意。所以在我的情况下,没有办法通过一个表来获取所有占用的内存,然后是完全相同的内存,但对于每一行都是分开的。非常感谢您的解释。

以上是关于PostgreSQL 列大小与表大小的主要内容,如果未能解决你的问题,请参考以下文章

postgresql查看数据库占用的物理存储空间大小

PostgreSQL 磁盘使用大小监控

为啥用户表的大小远小于 PostgreSQL 数据库中其他对象的大小

PostgreSQL-JDBC疑似bug:部分接口参数的表名列名必须全部小写

MS Access + Postgres 口音/不区分大小写的可编辑过滤器

使用带有自定义分隔符的 postgres 按字符大小复制文本文件