查 dba_ts_quotas 是最快最准的起点,它按用户+表空间双维度聚合,响应快、结果稳,不依赖 segment 扫描且不受空表干扰;需联合 dba_users 补全默认表空间用户,并用 dba_segments 验证真实物理占用。

查 dba_ts_quotas 是最快最准的起点
想直接知道「张三在 USERS 表空间里用了多少、配了多少」,dba_ts_quotas 是唯一按用户 + 表空间双维度聚合的视图。它不依赖 segment 扫描,不受空表(segment_created = 'NO')干扰,响应快、结果稳。
常见错误是用 dba_segments 去算——它漏掉没写入数据的表、不统计临时段和回滚段,总和永远对不上配额。
-
username和tablespace_name是联合主键,一行即一个用户在某表空间的配额状态 -
max_bytes = -1表示「无限制」,不是NULL;bytes是当前已用字节数(含预留未用空间) - 没被显式赋 quota 但有
UNLIMITED TABLESPACE权限的用户,不会出现在此视图中
补全默认表空间用户的隐式占用
有些用户根本不在 dba_ts_quotas 里,不代表他们没占空间——他们靠 default_tablespace 隐式写入。比如新建一张表没指定表空间,就落到默认表空间里。
别用 WHERE username IN (SELECT username FROM dba_ts_quotas) 过滤,会丢掉这部分人。
- 必须关联
dba_users,取default_tablespace非'SYSTEM'/'SYSAUX'的用户 -
dba_users.default_tablespace可能为空或指向已删表空间,查前先校验:SELECT tablespace_name FROM dba_tablespaces - 正确做法是
UNION ALL两部分:显式配额记录 + 默认表空间用户清单
dba_segments 用于验证真实物理占用
如果要确认「磁盘上到底分了多少 extent」,必须查 dba_segments。它反映真实分配空间,但慢、权限要求高、结果易误读。
- 只统计
segment_type IN ('TABLE', 'INDEX', 'LOBSEGMENT', 'LOBINDEX'),排除 rollback、undo 等系统段 -
owner对应用户名,tablespace_name IS NOT NULL必须加,否则 LOB 跨表空间时会漏 -
SUM(bytes)是原始字节,聚合后再除以1024*1024得 MB,别提前 round,避免小数误差累积 - 大库执行慢,建议加
WHERE owner NOT IN ('SYS','SYSTEM','OUTLN')排除系统用户
权限不足时别硬查 dba_segments
普通用户执行 SELECT * FROM dba_segments 报 ORA-00942,不是“没数据”,是没权限——这点常被当成查询失败而放弃。
- 先确认角色:
SELECT granted_role FROM session_roles WHERE granted_role IN ('DBA','SELECT_ANY_DICTIONARY') -
all_segments不等于“所有用户+自己”,它只返回你有 SELECT 权限的对象,大小值也仅限你能访问的部分 - RAC 环境下
dba_segments默认只查当前实例,跨实例需加@dblink或切实例连接
实际空间占用永远比配额视图多一层间接性:配额控制写入上限,default_tablespace 提供隐式落点,dba_segments 记录最终物理分配。三者口径不同,不能互相替代,但缺一不可。











