快速查看数据库每张表的大小(存储过程)

本文提供了一段 SQL Server 存储过程代码,用于快速查看数据库中每张表的大小,包括表名、记录数、预留空间、使用空间、索引占用空间及未用空间等关键信息。

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

代码来自网络,搜集并记录以免遗忘。
--快速查看数据库每张表的大小--

CREATE PROCEDURE [dbo].[sys_viewTableSpace]
AS

BEGIN

SET NOCOUNT ON;

CREATE TABLE [dbo].#tableinfo(
 表名 [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
 记录数 [int] NULL,
 预留空间 [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
 使用空间 [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
 索引占用空间 [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
 未用空间 [varchar](50) COLLATE Chinese_PRC_CI_AS NULL
)

insert into #tableinfo(表名, 记录数, 预留空间, 使用空间, 索引占用空间, 未用空间)
exec sp_MSforeachtable "exec sp_spaceused '?'"

select * from #tableinfo
order by 记录数 desc

drop table #tableinfo

END

exec sys_viewtablespace

<think>嗯,用户想查看Oracle数据库每张大小,需要查询每个占用的空间。这是个很实际的数据库管理需求,用户可能是DBA或开发人员,需要监控存储使用情况。 从引用内容看,站内资料提供了三种相关方法:引用[1]提到用Oracle管理视图和SQL语句查空间大小;引用[2]补充了联合查询空间总大小的方式;引用[3]则给出分区和索引的空间查询。这些虽然不直接对应需求,但提供了关键线索——应该使用USER_SEGMENTS或DBA_SEGMENTS视图。 用户的核心需求是"所有大小",重点在"每个"的细分数据。需要区分两种场景:普通用户查自己的用USER_SEGMENTS,DBA查全库用DBA_SEGMENTS。考虑到权限问题,应该优先推荐用户级方案。 具体实现时要注意: 1. 必须包含名和空间大小两列 2. 空间单位统一转换为MB更友好 3. 按大小降序排列方便查看热点 4. 如果有LOB等特殊段类型需要额外处理 用户没提分区,但实际环境中分区很常见,所以补充分区的查询方法会更有价值。另外索引空间经常和空间混淆,可以单独说明避免误解。 最后生成的参考问题要覆盖延伸需求:比如排序依据、LOB字段处理、自动化监控等,这些都是实际运维中自然衍生的需求点。尤其空间排序和总大小统计,用户下一步很可能就会问到。</think>好的,在Oracle数据库中查询**所有大小**(即每个占用的空间),可以使用数据字典视图 `USER_SEGMENTS`(查询当前用户拥有的对象)或 `DBA_SEGMENTS`(需要DBA权限,查询数据库中所有对象)。以下是清晰的步骤和SQL语句: ### 方法 1:查询当前用户拥有的所有大小 (使用 `USER_SEGMENTS`) ```sql SELECT segment_name AS table_name, SUM(bytes) / 1024 / 1024 AS size_mb -- 将字节转换为兆字节(MB) FROM user_segments WHERE segment_type = 'TABLE' -- 只查询类型 GROUP BY segment_name ORDER BY size_mb DESC; -- 按大小降序排列,方便查看 ``` **说明:** 1. `segment_name`: 名。 2. `bytes`: 该段(在这里是)占用的字节数。 3. `SUM(bytes) / 1024 / 1024`: 将字节数转换为兆字节(MB)。`/1024` 得到KB,再 `/1024` 得到MB。 4. `segment_type = 'TABLE'`: 过滤出类型为 'TABLE' 的段。这是指普通的堆组织(Heap-Organized Table)。 5. `GROUP BY segment_name`: 按名分组,因为一个可能由多个区(extents)组成,分布在不同的段中(虽然单个通常对应一个段,但分区或包含LOB列的会对应多个段)。 6. `ORDER BY size_mb DESC`: 按计算出的大小(MB)降序排序,这样最大的会排在最前面。 ### 方法 2:查询数据库中所有大小 (使用 `DBA_SEGMENTS`,需要 DBA 权限) ```sql SELECT owner, -- 的所有者(模式名) segment_name AS table_name, SUM(bytes) / 1024 / 1024 AS size_mb FROM dba_segments WHERE segment_type = 'TABLE' GROUP BY owner, segment_name ORDER BY owner, size_mb DESC; -- 先按所有者排序,再按大小降序 ``` **说明:** 1. 与 `USER_SEGMENTS` 类似,但增加了 `owner` 列,显示所属的模式(用户)。 2. 使用 `dba_segments` 视图需要用户具有 `SELECT ANY DICTIONARY` 或 `DBA` 角色权限。 3. `GROUP BY owner, segment_name`: 按所有者和名分组。 4. `ORDER BY owner, size_mb DESC`: 先按所有者排序,在每个所有者下,再按大小降序排列。 ### 重要注意事项 1. **LOB 列的空间占用**:上面的查询主要统计了数据段(以及上的索引组织IOT的溢出段等)的大小。如果包含 `CLOB`, `BLOB`, `NCLOB` 或 `BFILE` 类型的列,这些列的数据通常存储在**独立的LOB段**中。上面的查询**不会**包含这些LOB段的空间。要获取包含LOB列的的**总空间**(段 + LOB段),需要更复杂的查询,例如: ```sql SELECT table_name, (SELECT SUM(bytes) / 1024 / 1024 FROM user_segments WHERE segment_name = table_name OR segment_name IN ( SELECT segment_name FROM user_lobs WHERE table_name = ut.table_name) ) AS total_size_mb FROM user_tables ut ORDER BY total_size_mb DESC NULLS LAST; ``` (此查询仅为思路示例,实际执行可能需要调整,且可能效率不高,LOB关联复杂时建议分开查询段和LOB段再求和)。 2. **分区**:对于分区,`USER_SEGMENTS`/`DBA_SEGMENTS` 中的 `segment_type` 通常是 `TABLE PARTITION` 或 `TABLE SUBPARTITION`,而不是简单的 `TABLE`。上面的查询使用 `segment_type = 'TABLE'` 会**遗漏分区**。要查询分区大小,通常需要: ```sql SELECT table_name, partition_name, SUM(bytes) / 1024 / 1024 AS partition_size_mb FROM user_segments WHERE segment_type LIKE 'TABLE%PARTITION' -- 匹配 TABLE PARTITION 和 TABLE SUBPARTITION GROUP BY table_name, partition_name ORDER BY table_name, partition_name; ``` 或者查询分区的总大小: ```sql SELECT table_name, SUM(bytes) / 1024 / 1024 AS total_size_mb FROM user_segments WHERE segment_type LIKE 'TABLE%PARTITION' OR (segment_type = 'TABLE' AND EXISTS ( -- 防止遗漏非分区 SELECT 1 FROM user_tables ut WHERE ut.table_name = user_segments.segment_name AND ut.partitioned = 'YES')) GROUP BY table_name ORDER BY total_size_mb DESC; ``` (非分区用 `TABLE`,分区用 `TABLE%PARTITION`,这个查询试图合并两者)。更准确的做法是关联 `USER_TABLES` 视图的 `PARTITIONED` 列。 3. **索引空间**:上述查询**不包含**上索引占用的空间。索引存储在独立的段中(`segment_type = 'INDEX'`)。查询索引大小需单独使用类似语句,将 `segment_type` 改为 `'INDEX'`。 4. **空间计算**:`bytes` 列给出的是段**当前分配**的区(extents)的总大小。这不一定是中实际数据占用的精确字节数(可能存在块内空闲空间),但反映了该对象在空间中实际占用的存储空间量,是管理和优化的关键指标[^1][^2][^3]。 5. **临时/Undo 空间**:这些查询统计的是存储在**永久空间**中的用户数据。临时和Undo段的信息需要使用其他视图(如 `DBA_TEMP_FILES`, `V$UNDOSTAT`)。 ### 总结 * 要快速查看**当前用户**下**非分区**的近似大小(不包含LOB和索引),使用**方法1** (`USER_SEGMENTS`)。 * 要查看**数据库中所有用户**的大小(需要DBA权限),使用**方法2** (`DBA_SEGMENTS`)。 * 对于**包含LOB列**的或**分区**,需要额外的、更复杂的查询来获取更全面的空间信息[^3]。 * 上**索引**的空间占用需单独查询 `segment_type = 'INDEX'`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值