想知道Oracle里表空间用多少了怎么查才方便又快点
- 问答
- 2026-01-19 09:30:11
- 2
想知道Oracle数据库里表空间用了多少,这个问题确实是日常运维和开发中经常会遇到的,想查得又方便又快,关键是要知道用哪些SQL语句,以及怎么看懂结果,下面我就直接根据Oracle官方文档和一些常见的DBA实践经验,来给你梳理一下方法。
最核心、最常用的方法是查询 DBA_DATA_FILES 和 DBA_FREE_SPACE 这两个数据字典视图,你可以把表空间想象成一个大的储物柜,DBA_DATA_FILES 是看这个柜子总共有多少个隔间(数据文件),每个隔间有多大;而 DBA_FREE_SPACE 是看每个隔间里还剩下多少空地方,把两者一结合,就能算出用了多少。
一个典型的查询语句是这样的(来源:基于Oracle SQL参考手册中关于数据字典视图的常见用法):
SELECT
a.tablespace_name,
ROUND(SUM(a.bytes) / (1024 * 1024 * 1024), 2) total_size_gb,
ROUND(SUM(a.bytes - NVL(b.free_bytes, 0)) / (1024 * 1024 * 1024), 2) used_size_gb,
ROUND(SUM(NVL(b.free_bytes, 0)) / (1024 * 1024 * 1024), 2) free_size_gb,
ROUND((SUM(a.bytes - NVL(b.free_bytes, 0)) / SUM(a.bytes)) * 100, 2) used_percentage
FROM
dba_data_files a
LEFT JOIN (
SELECT
tablespace_name,
SUM(bytes) free_bytes
FROM
dba_free_space
GROUP BY
tablespace_name
) b ON a.tablespace_name = b.tablespace_name
GROUP BY
a.tablespace_name
ORDER BY
used_percentage DESC;
怎么看这个结果:
TABLESPACE_NAME:表空间的名称。TOTAL_SIZE_GB:这个表空间的总大小,单位是GB。USED_SIZE_GB:已经使用了多少GB。FREE_SIZE_GB:还剩下多少GB可用。USED_PERCENTAGE:使用率百分比,这是最关键的指标,通常我们按这个降序排列,一眼就能看出哪个表空间最满。
这个方法又快又直接,能让你马上对数据库的表空间使用情况有个整体把握。
这里有一个很重要的点需要注意(来源:Oracle数据库管理员指南中关于自动段空间管理的概念):上面的查询计算的是“已分配”的空间和使用率。 对于现代Oracle数据库(通常使用本地管理表空间和自动段空间管理ASSM),数据文件中的空间分配给你了,但你不一定真的用掉了,你建了一张表,即使里面没数据,Oracle也可能先给它分配一块不小的空间(称为区间Extent),这种方法查出的“已使用”空间,可能包含了大量虽然被分配但实际空闲的空间。
如果你想知道更“真实”的空间使用情况,即实际存放了数据的空间有多大,就需要深入到“段”(Segment)级别去分析,段就是像表、索引这些数据库对象真正占用的空间单元,这时,我们可以查询 DBA_SEGMENTS 视图。
SELECT
tablespace_name,
ROUND(SUM(bytes) / (1024 * 1024 * 1024), 2) used_by_segments_gb
FROM
dba_segments
GROUP BY
tablespace_name
ORDER BY
used_by_segments_gb DESC;
这个查询会告诉你每个表空间里,所有表、索引等对象实际占用的空间总和,这个数字通常会比第一种方法算出来的“已使用空间”要小。
哪种方法更好呢? 这取决于你的目的:
- 监控告警:如果你是为了设置警报,比如表空间使用率超过90%就发邮件,那么第一种方法(基于数据文件和空闲空间)是标准做法,因为它反映的是磁盘上数据文件的真实占用情况,使用率接近100%意味着数据库无法再分配新的空间,可能会导致应用失败,这是最需要警惕的。
- 空间分析:如果你是想分析“我的数据到底占了多大地方?”或者“有没有哪个表或索引特别大,可以清理一下?”,那么第二种方法(基于段)更准确,它能帮你找到空间的真正消耗者。
为了方便,你可以把这两个查询结合起来看,这样信息更全面,你可以看到一个表空间第一种方法算出来用了80%,但第二种方法发现实际数据只占了30%,那说明这个表空间里有大约50%的空间是“水分”(分配了但未使用的区间),这可能意味着有些对象设置的增长参数(如NEXT_EXTENT)过大,或者有很多被删除数据后留下的空闲空间。
除了这些基本查询,Oracle还提供了一些现成的脚本来帮助DBA,其中最著名的可能就是 $ORACLE_HOME/rdbms/admin 目录下的 utlspace.sql 脚本了(来源:Oracle服务器端参考指南),这个脚本会创建一个叫 DBMS_SPACE_ADMIN 的包(其实主要是utlspace.sql创建相关对象),但它更常用于一些高级的空间管理操作,对于快速查看,上面那两个查询已经足够。
对于临时表空间和撤销表空间这两种特殊的表空间,它们的空间使用是动态变化的,查询方式稍有不同。
查临时表空间使用情况(来源:Oracle数据库参考中关于V$TEMP_SPACE_HEADER视图的描述): 临时表空间主要用于排序等操作,可以这样查:
SELECT
tablespace_name,
ROUND(SUM(total_blocks) * (SELECT value FROM v$parameter WHERE name = 'db_block_size') / (1024*1024*1024), 2) total_gb,
ROUND(SUM(used_blocks) * (SELECT value FROM v$parameter WHERE name = 'db_block_size') / (1024*1024*1024), 2) used_gb,
ROUND(SUM(free_blocks) * (SELECT value FROM v$parameter WHERE name = 'db_block_size') / (1024*1024*1024), 2) free_gb
FROM
v$temp_space_header
GROUP BY
tablespace_name;
这里用的是动态性能视图 V$TEMP_SPACE_HEADER。
查撤销表空间使用情况(来源:Oracle数据库性能调优指南中关于监控撤销表空间的部分): 撤销表空间用于存储事务的回滚信息,一个常用的查询是:
SELECT
tablespace_name,
ROUND(SUM(bytes) / (1024*1024*1024), 2) size_gb,
ROUND(SUM(bytes) - ROUND(SUM(blocks) * (SELECT value FROM v$parameter WHERE name = 'db_block_size'), 2) used_gb
FROM
dba_undo_extents
GROUP BY
tablespace_name;
但更直观的方法是结合 DBA_DATA_FILES 和 V$ROLLSTAT, V$TRANSACTION 等视图,不过那会复杂一些,一个简单的概览可以直接看 V$UNDOSTAT。
为了真正“方便”,你可以把这些查询保存成SQL脚本文件,比如叫 check_tbs.sql,放在一个固定位置,每次需要检查时,只需要在SQL*Plus或者SQL Developer里执行 @/path/to/check_tbs.sql 就行了,一秒钟出结果,你甚至可以写一个Shell脚本,定期运行这个SQL并邮件发送结果,实现自动化监控。
最快最方便的办法就是:日常监控用第一个查询(DBA_DATA_FILES + DBA_FREE_SPACE),重点关注使用率百分比;需要深入分析真实数据大小时,结合第二个查询(DBA_SEGMENTS),记住这两个核心点,就能应对绝大多数查看表空间大小的场景了。

本文由寇乐童于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/83584.html
