查看整个数据库的总大小
当我们谈论“数据库大小时”,指的是构成数据库的所有物理文件在操作系统级别的总占用空间,这主要包括数据文件、控制文件、重做日志文件和临时文件。

我们可以通过查询不同的数据字典视图并将结果汇总来获得这个总值,以下SQL语句可以计算出数据库的总大小(以GB为单位):
SELECT
ROUND((SUM(bytes) / (1024 * 1024 * 1024)), 2) AS "Total Database Size (GB)"
FROM (
SELECT SUM(bytes) bytes FROM dba_data_files
UNION ALL
SELECT SUM(bytes) bytes FROM dba_temp_files
UNION ALL
SELECT SUM(bytes * members) bytes FROM v$log
UNION ALL
SELECT SUM(block_size * file_size_blks) bytes FROM v$controlfile
);
查询解析:
dba_data_files: 包含所有数据文件的信息,SUM(bytes)计算所有数据文件的总字节数。dba_temp_files: 包含所有临时文件的信息。v$log: 包含所有重做日志组的信息,bytes * members计算每个日志组所有成员的总大小。v$controlfile: 包含控制文件的信息,block_size * file_size_blks计算每个控制文件的大小。UNION ALL将所有查询结果合并,最外层的SUM则将所有文件大小相加,最后通过ROUND函数转换为GB并保留两位小数。
执行此查询后,你将得到一个精确的数值,它代表了数据库在磁盘上占用的全部物理空间。
查看表空间的大小与使用率
表空间是Oracle数据库逻辑存储结构的核心,数据被存储在表空间的数据文件中,监控每个表空间的大小和使用率是DBA最频繁的操作之一,这有助于我们了解哪些表空间空间紧张,需要及时扩容。
下面的查询可以清晰地展示每个表空间的总大小、已使用空间、剩余空间以及使用率百分比:
SELECT
a.tablespace_name,
ROUND(a.total_space_mb, 2) AS "Total Size (MB)",
ROUND(a.total_space_mb - b.free_space_mb, 2) AS "Used Space (MB)",
ROUND(b.free_space_mb, 2) AS "Free Space (MB)",
ROUND((a.total_space_mb - b.free_space_mb) / a.total_space_mb * 100, 2) AS "Usage %"
FROM (
SELECT tablespace_name, SUM(bytes) / (1024 * 1024) AS total_space_mb
FROM dba_data_files
GROUP BY tablespace_name
) a,
(
SELECT tablespace_name, SUM(bytes) / (1024 * 1024) AS free_space_mb
FROM dba_free_space
GROUP BY tablespace_name
) b
WHERE a.tablespace_name = b.tablespace_name
ORDER BY "Usage %" DESC;
查询解析与结果展示:
这个查询通过两个子查询分别计算表空间的总大小和剩余空间,然后通过表空间名进行关联。

- 子查询a (
dba_data_files): 计算每个表空间所有数据文件分配的总空间。 - 子查询b (
dba_free_space): 计算每个表空间内所有数据段的空闲区总和。 - 关联计算: 总大小减去剩余空间即为已使用空间,再除以总大小便得到使用率。
查询结果会以表格形式呈现,示例如下:
| TABLESPACE_NAME | Total Size (MB) | Used Space (MB) | Free Space (MB) | Usage % |
|---|---|---|---|---|
| USERS | 500 | 25 | 75 | 05 |
| SYSTEM | 800 | 50 | 50 | 06 |
| SYSAUX | 600 | 10 | 90 | 02 |
| UNDOTBS1 | 1000 | 00 | 00 | 00 |
通过这个表格,可以一目了然地发现USERS表空间的使用率已高达95%,需要立即关注并采取扩容措施。
查看特定用户(Schema)所占空间
在多租户或多应用共享数据库的环境中,我们可能需要了解某个特定用户(即Schema)占用了多少空间,这对于资源隔离和成本分摊非常有用。
dba_segments视图记录了数据库中所有段(如表、索引、LOB等)的分配空间信息,我们可以按用户进行分组汇总:
SELECT
owner,
ROUND(SUM(bytes) / (1024 * 1024), 2) AS "Size (MB)"
FROM
dba_segments
WHERE
owner = 'SCOTT' -- 将 'SCOTT' 替换为你想查询的用户名
GROUP BY
owner;
如果需要查看所有用户的空间占用排行,可以去掉WHERE子句并按大小排序:
SELECT
owner,
ROUND(SUM(bytes) / (1024 * 1024), 2) AS "Size (MB)"
FROM
dba_segments
GROUP BY
owner
ORDER BY
"Size (MB)" DESC;
查看单个表的大小
当进行性能诊断或数据迁移时,定位到具体某个表的大小是必要的,同样,我们可以利用dba_segments视图来精确查询。
SELECT
segment_name AS "Table Name",
segment_type,
ROUND(bytes / (1024 * 1024), 2) AS "Size (MB)"
FROM
dba_segments
WHERE
owner = 'SCOTT' -- 表所属用户
AND segment_name = 'EMP'; -- 表名
注意: 此处查询到的大小是表这个“段”所分配的空间,它可能比表中实际数据占用的空间要大,因为Oracle会预留一些空间用于未来的数据插入(PCTFREE等参数控制)。

相关问答FAQs
问题1:查询结果中的“已使用空间”和表中实际数据量有什么区别?
解答: 这是一个很关键的区别,我们通过dba_segments或计算表空间使用率得到的“已使用空间”,指的是Oracle为某个对象(如表、索引)已经分配的存储空间,而表中实际数据量,通常指所有行数据加起来的实际字节数,由于Oracle存储管理机制(如块格式、行迁移、PCTFREE预留空间等),分配的空间通常会大于实际数据量,分配空间是“占着坑”,实际数据量是“坑里的人”,两者之间总会有一定的差距。
问题2:我没有DBA权限,只是一个普通开发者,如何查看我能访问的对象的大小?
解答: 没有DBA权限的用户无法查询dba_开头的视图,这些视图包含整个数据库的信息,Oracle提供了user_开头的视图,它们只显示当前用户所拥有的对象信息,你可以使用user_segments来替代dba_segments,使用user_free_space来替代dba_free_space。
查看当前用户下所有表的大小,可以使用以下SQL:
SELECT
segment_name AS "Table Name",
segment_type,
ROUND(bytes / (1024 * 1024), 2) AS "Size (MB)"
FROM
user_segments
WHERE
segment_type = 'TABLE';
这样,你就可以在不具备DBA权限的情况下,有效管理自己schema下的空间资源了。