pg_class家族成员(名字、类型、引用、描述),附带几个实例,简单易懂

本文深入解析了PostgreSQL数据库中pg_class表的结构和用途,详细介绍了其各字段的意义,包括表名、模式、行类型、所有者等,并提供了查询表大小、记录数及中文备注的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pg_class家族成员(名字、类型、引用、描述)

pg_ class 是数据字典最重要的一个表,它保存着所有表、视图、序列、索引的原数据信息,每一个DDL/DML操作都必须跟这个表发生联系,在进行整库操作时经常使用到pg_class里面的东西,把它们整理出来,对数据库的了解有很大帮助。

**名字            类型	    引用	          描述**
relname	          name	 	              表、索引、视图等的名字。
relnamespace	  oid  	pg_namespace.oid  包含这个关系的名字空间(模式)的 OID
reltype           oid   pg_type.oid	      对应这个表的行类型的数据类型(索引为零,它们没有 pg_type 记录)。
relowner	      oid	pg_authid.oid	  关系所有者
relam	          oid	pg_am.oid	      如果行是索引,那么就是所用的访问模式(B-tree, hash 等等)
relfilenode	      oid	 	              这个关系在磁盘上的文件的名字,如果没有则为 0
reltablespace	  oid	pg_tablespace.oid 这个关系存储所在的表空间。如果为零,则意味着使用该数据库的缺省表空间。如果关系在磁盘上没有文件,则这个字段没有什么意义。
relpages	      int4	 	              以页(大小为 BLCKSZ)的此表在磁盘上的形式的大小。它只是规划器用的一个近似值,是由 VACUUM, ANALYZE 和几个 DDL 命令,比如 CREATE INDEX 更新。
reltuples	      float4	       	      表中行的数目。只是规划器使用的一个估计值,由 VACUUM, ANALYZE 和几个 DDL 命令,比如 CREATE INDEX 更新。
reltoastrelid     oid	pg_class.oid 	  与此表关联的 TOAST 表的 OID ,如果没有为 0 。TOAST 表在一个从属表里"离线"存储大字段。
reltoastidxid     oid	pg_class.oid	  对于 TOAST 表是它的索引的 OID ,如果不是 TOAST 表则为 0
relhasindex	      bool	                  如果它是一个表而且至少有(或者最近有过)一个索引,则为真。它是由 CREATE INDEX 设置的,但 DROP INDEX 不会立即将它清除。如果 VACUUM 现一个表没有索引,那么它将清理 relhasindex 。
relisshared	      bool	                  如果该表在整个集群中由所有数据库共享则为真。只有某些系统表(比如 pg_database)是共享的。
relkind           char	                  r = 普通表, i = 索引, S = 序列, v = 视图, c = 复合类型, t = TOAST 表
relnatts	      int2	 	              关系中 用户字段数目(除了系统字段以外)。在 pg_attribute 里肯定有相同数目对应行。又见 pg_attribute.attnum
relchecks	      int2	 	              表里的检查约束的数目;参阅 pg_constraint 表
reltriggers       int2	 	              表里的触发器的数目;参阅 pg_trigger 表
relukeys	      int2	 	              未使用(不是唯一值的数目)
relfkeys	      int2	              	  未使用(不是表中外键的数目)
relrefs	          int2	 	              未使用
relhasoids	      bool	 	              如果为关系中每行都生成一个 OID 则为真
relhaspkey	      bool	 	              如果这个表有一个(或者曾经有一个)主键,则为真。
relhasrules       bool	 	              如表有规则就为真;参阅 pg_rewrite 表
relhassubclass 	  bool	 	              如果有(或者曾经有)任何继承的子表,为真。
relfrozenxid      xid	 	              该表中所有在这个之前的事务 ID 已经被一个固定的("frozen")事务 ID 替换。这用于跟踪该表是否需要为了防止事务 ID 重叠或者允许收缩 pg_clog 而进行清理。如果该关系不是表则为零(InvalidTransactionId)。
relacl    	      aclitem[]	          	  访问权限。参阅 GRANT 和 REVOKE 获取详细信息。
reloptions     	 text[]	 	              访问方法特定的选项,使用"keyword=value"格式的字符串

例1:查看各个数据库表大小(不包含索引),以及表数据量

select table_schema,TABLE_NAME,reltuples,pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"'))
from pg_class,information_schema.tables where relname=TABLE_NAME
ORDER BY reltuples desc limit 20

例2:查询数据表名称及中文备注、每个表的记录数:

SELECT a.relname AS name,
       b.description AS comment,
       a.reltuples
  FROM pg_class a
       LEFT OUTER JOIN pg_description b ON b.objsubid=0 AND a.oid = b.objoid
 WHERE a.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname='public')  AND a.relkind='r'
 ORDER BY a.relname;

例3 : 在posgres数据库中查询pg_class的内容

select * from pg_class

在这里插入图片描述

### PostgreSQL 中 `Index Only Scan` 的工作原理 在 PostgreSQL 中,`Index Only Scan` 是一种高效的查询执行方式。当查询只需要访问索引中的列而不需要回表获取额外的数据时,可以触发这种扫描模式。这种方式能够显著减少 I/O 开销并提升查询性能。 对于 `pg_class` 表及其索引 `pg_class_relname_nsp_index` 来说,该索引通常基于 `(relnamespace, relname)` 列创建[^1]。如果查询仅涉及这些索引覆盖的列,则可以通过 `Index Only Scan` 完成数据检索,而不必访问实际的表数据页。 #### 查询计划分析 假设有一个查询如下: ```sql SELECT relname FROM pg_class WHERE relnamespace = 2200 AND relkind = 'r'; ``` 在这种情况下,如果 `pg_class_relname_nsp_index` 能够完全覆盖所需的列(即 `relname`, `relnamespace`, 和可能隐含的条件),则优化器会选择 `Index Only Scan`。这意味着它会直接从索引中读取所需的信息,而不是通过索引来定位对应的表行再从中提取数据。 #### 性能优化的关键因素 1. **可见性位图**:为了确保返回的结果是最新的,PostgreSQL 需要验证每一条记录是否对当前事务可见。这涉及到检查堆元组上的可见性标志。即使使用了 `Index Only Scan`,也可能因为 MVCC 的原因导致少量随机 I/O 发生。 2. **VACUUM 维护**:定期运行 VACUUM 可以标记更多元组为全量可见状态,从而进一步提高 `Index Only Scan` 的效率。这是因为减少了因确认元组可见性而导致的实际表访问次数。 3. **统计信息准确性**:保持最新的统计数据有助于规划器做出更优的选择。例如,准确估计满足过滤条件的行数可以帮助决定何时采用 `Index Only Scan` 或其他类型的扫描方法。 #### 示例代码展示 下面是一个简单的例子来演示如何利用 `Index Only Scan`: ```sql -- 创建测试环境 CREATE TABLE test_table(id serial PRIMARY KEY, data text); INSERT INTO test_table(data) SELECT md5(random()::text) FROM generate_series(1,10000); -- 建立适合 Index Only Scan 的索引 CREATE INDEX idx_test_data ON test_table(data); EXPLAIN ANALYZE SELECT data FROM test_table WHERE id BETWEEN 1 AND 10; ``` 在这个例子中,由于我们只选择了被索引所覆盖的字段 (`data`) 并施加了一个范围限制于主键之上,因此有可能观察到一次纯粹依赖索引完成操作的情况——也就是所谓的 `Index Only Scan`. --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值