Postgresql统计所有表的基本信息(如行数、大小等)

pg_class
目录 pg_class 记录表和几乎所有具有列或者像表的东西。这包括索引(但还要参见 pg_index )、序列、视图、物化视图、组合类型和TOAST表。
pg_class 中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。例如, relhasindex 由 CREATE INDEX 设置,但它从不会被DROP INDEX 清除。作为替代, VACUUM 会在找到无索引表后清除其 relhasindex 。这种安排避免了竞争条件并且提高了并发性


本文来自 PostgreSQL_HighGoDB 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/pg_hgdb/article/details/79455123?utm_source=copy

名称

类型

参考

描述

oid

oid

 

行标识符(隐藏属性;必须明确选择)

relname

name

 

表格,索引,视图等的名称

relnamespace

oid

pg_namespace.oid

包含此relation的名称空间的oid

reltype

oid

pg_type .oid

与此表行类型对应的数据类型的oid(如果有的话)(对于没有pg_type条目的索引,为零 )

reloftype

oid

pg_type .oid

对于类型表,基础复合类型的oid,对于所有其他relation为零

relowner

oid

pg_authid.oid

relation的所有者

relam

oid

pg_am.oid

如果这是一个索引,则使用的访问方法(B-树,散列等)

relfilenode

oid

 

该relation的磁盘文件的名称; 零表示这是一个“映射”relation,其磁盘文件名由低级状态决定

reltablespace

oid

pg_tablespace.oid

存储该relation的表空间。如果为零,则隐含数据库的默认表空间。(如果relation没有磁盘上的文件,则无意义。)

relpages

int4

 

该表的磁盘表示的大小(页面大小为BLCKSZ)。这只是计划者使用的估计值。它由 VACUUM,ANALYZE和一些DDL命令(如 CREATE INDEX)更新。

reltuples

float4

 

表中的行数。这只是计划者使用的估计值。它由VACUUM,ANALYZE和一些DDL命令(如CREATE INDEX)更新。

relallvisible

int4

 

在表格的可见性图中标记为全部可见的页面数。这只是计划者使用的估计值。它由VACUUM,ANALYZE和一些DDL命令(如CREATE INDEX)更新。

reltoastrelid

oid

pg_class .oid

与此表关联的TOAST表的oid,如果没有,则为0。TOAST表在“辅助表”中存储“超出行”的大型属性 。

relhasindex

bool

 

如果这是一个表并且它有(或最近有)任何索引,则为真

relisshared

bool

 

如果此表在群集中的所有数据库之间共享,则为true。只有某些系统目录(如 pg_database)被共享。

relpersistence

char

 

p =永久表, u =未记录表,t =临时表

relkind

char

 

r =普通表, i =索引,S =序列,v =视图,m =物化视图, c =复合类型,t = TOAST表,f =外部表

relnatts

int2

 

relation中的用户列数(系统列未计数)。pg_attribute中必须有许多相应的条目。另见pg_attribute.attnum。

relchecks

int2

 

表上CHECK约束的数量; 请参阅pg_constraint目录

relhasoids

bool

 

如果我们为relation的每一行生成oid,则为真

relhaspkey

bool

 

如果表具有(或曾经有)主键,则为真

relhasrules

bool

 

如果表具有(或曾经有)规则,则为真; 请参阅pg_rewrite目录

relhastriggers

bool

 

如果表具有(或曾经有)触发器,则为真; 请参阅 pg_trigger目录

relhassubclass

bool

 

如果表有(或曾经有过)任何继承孩子,则为真

relrowsecurity

bool

 

如果表已启用行级安全性,则为true; 请参阅 pg_policy目录

relforcerowsecurity

bool

 

如果行级别安全性(启用时)也为true,则也适用于表所有者; 请参阅pg_policy目录

relispopulated

bool

 

如果relation被填充,则为真(对于除某些实例化视图之外的所有relation都是如此)

relreplident

char

 

用于为行构成“副本标识”的列:d = default(主键,如果有的话),n =无,f =所有列 i =具有indisreplident set的索引或default

relfrozenxid

xid

 

在此表之前的所有交易ID已被替换为永久(“冻结”)交易ID。这用于跟踪是否需要将表抽真空以防止事务ID环绕或允许缩小pg_clog。零(InvalidTransactionId)如果relation不是一个表。

relminmxid

xid

 

在此表之前的所有多重作业ID已由该事务ID替换。这用于跟踪是否需要将表抽真空以防止多轴实现ID 绕回或允许缩小pg_multixact。零(InvalidMultiXactId)如果relation不是一个表。

relacl

aclitem[]

 

访问权限; 看到GRANTREVOKE的细节

reloptions

text[]

 

特定于访问方法的选项,如“keyword = value”字符串

1、查询某Schema下的每张表的记录数:
select relname as TABLE_NAME, reltuples as rowCounts from pg_class where relkind = 'r' and relnamespace = (select oid from pg_namespace where nspname='public') order by rowCounts desc;
 
  • 1

因懒惰的方式维护,当有新的数据插入表中时,上述命令执行结果不会改变,需要刷新数据表,需先执行:

vacuum tablename     #更新某个表
vacuum               #在某个数据库中执行直接更新该数据库所有表
 
  • 1
  • 2

vacuum的效果:
1.1释放,再利用 更新/删除的行所占据的磁盘空间.
1.2更新POSTGRESQL查询计划中使用的统计数据
1.3防止因事务ID的重置而使非常老的数据丢失。

第一点的原因是PostgreSQL数据的插入,更新,删除操作并不是真正放到数据库空间.如果不定期释放空间的话,由于数据太多,查询速度会巨降.
第二点的原因是PostgreSQL在做查询处理的时候,为了是查询速度提高,会根据统计数据来确定执行计划.如果不及时更新的话,查询的效果可能不如预期.
第三点的原因是PostgreSQL中每一个事务都会产生一个事务ID,但这个数字是有上限的. 当事务ID达到最大值后,会重新从最小值开始循环.这样如果不及时把以前的数据释放掉的话,原来的老数据会因为事务ID的丢失而丢失掉。

vacuum原理及用法可参考:
https://www.cnblogs.com/pengai/p/8073218.html
http://blog.itpub.net/29989552/viewspace-2128914/
2、查询表名和表注释

select relname as tabname,cast(obj_description(relfilenode,'pg_class') as varchar) as comment from pg_class c where   relname ='table_name' ;
 
  • 1

2、查询字段名、字段类型及字段长度和字段注释

select a.attnum,a.attname,
concat_ws('',t.typname,SUBSTRING(format_type(a.atttypid,a.atttypmod) from '\(.*\)')) as type,d.description from pg_class c, pg_attribute a , pg_type t, pg_description d where  c.relname = 'table_name' and a.attnum>0 and a.attrelid = c.oid and a.atttypid = t.oid and  d.objoid=a.attrelid and d.objsubid=a.attnum
 
  • 1
  • 2

pg_attribute可见:
https://www.cnblogs.com/stephen-liu74/archive/2012/05/25/2305415.html
3、查询表的大小

select pg_size_pretty(pg_relation_size('table_name'));
 
  • 1

4、查询所有表并按大小排序

SELECT 
table_schema || '.' || table_name 
AS table_full_name, pg_size_pretty(pg_total_relation_size('"' ||table_schema || '"."' || table_name || '"')) AS size
FROM 
information_schema.tables
ORDER BY
    pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')
DESC limit 20
 

可参考 http://blog.51yip.com/pgsql/1525.html
5、查出所有表按大小排序并分离data与index

SELECT
    table_name,
    pg_size_pretty(table_size) AS table_size,
    pg_size_pretty(indexes_size) AS indexes_size,
    pg_size_pretty(total_size) AS total_size
FROM (
    SELECT
        table_name,
        pg_table_size(table_name) AS table_size,
        pg_indexes_size(table_name) AS indexes_size,
        pg_total_relation_size(table_name) AS total_size
    FROM (
        SELECT ('"' || table_schema || '"."' || table_name || '"') AS table_name
        FROM information_schema.tables
    ) AS all_tables
    ORDER BY total_size DESC
) AS pretty_sizes
 

6、统计各数据库占用的磁盘大小

SELECT d.datname AS Name,  pg_catalog.pg_get_userbyid(d.datdba) AS Owner,
    CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')
        THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))
        ELSE 'No Access'
    END AS SIZE
FROM pg_catalog.pg_database d
    ORDER BY
    CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')
        THEN pg_catalog.pg_database_size(d.datname)
        ELSE NULL
    END DESC -- nulls first
    LIMIT 20
 
posted @ 2023-07-13 13:23  小林子哈哈  阅读(1356)  评论(0编辑  收藏  举报