跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Oracle如何查看用户对象的大小占用_结合权限与空间视图

查用户表大小必须用user_segments而非user_tables,因后者仅存元数据;user_segments中segment_name需严格匹配(默认大写),且同一表可能有多个segment(如LOB)。 查用户表大小必须用
user_segments
,不是
user_tables
user_tables
只存元数据(比如列名、状态),不记录空间占用。真正反映物理大小的是
user_segments
——它对应磁盘上实际分配的段(segment)。误用
user_tables
会导致查不到任何字节数,甚至报“no rows selected”。 关键点:
segment_name
必须大写,且与表名完全一致(Oracle 默认转大写,但若建表时加了双引号定义小写名,则需按原样匹配) 同一个表可能有多个 segment(如带 LOB 列时,
LOBSEGMENT
和
LOBINDEX
会单独计) 查询前确保你有访问
user_segments
的权限;普通用户默认可查,但若被显式收回
SELECT_CATALOG_ROLE
,则会报
ORA-00942: table or view does not exist
示例(查当前用户下
EMPLOYEES
表总大小):
SELECT SUM(bytes) / 1024 / 1024 AS "size_mb" FROM user_segments WHERE segment_name = 'EMPLOYEES';
dba_segments
和
user_segments
权限差异直接影响结果范围 用
dba_segments
能看到所有用户的对象大小,但前提是已授予
SELECT ANY DICTIONARY
或
DBA
角色。没权限时直接执行会报
ORA-00942
,而不是返回空结果——这点容易误判为“没数据”。 常见错误场景: 开发连测试库用普通账号,却复制 DBA 脚本里的
dba_segments
查询,结果报错 误以为
all_segments
是“所有用户+自己”,其实它只显示当前用户有权限访问的对象(比如被授予
SELECT
的其他用户表),大小值也仅反映你能读到的部分 在 RAC 环境中,
dba_segments
默认只查当前实例,跨实例需加
@dblink
或切到对应实例连接 安全做法:先确认角色
SELECT granted_role FROM session_roles WHERE granted_role IN ('DBA', 'SELECT_ANY_DICTIONARY');
精确查某张表真实数据量,得用
dbms_space.object_space_usage
user_segments.bytes
返回的是分配空间(包括未使用的高水位线以上空间),而
dbms_space.object_space_usage
能给出已使用字节数、行数估算、链式行比例等更贴近实际的数据。 注意限制: oracle知识库 oracle知识库下载 下载 必须用 PL/SQL 块执行,不能直接 SELECT 需要
EXECUTE
权限 on
dbms_space
(通常随
CONNECT
或
RESOURCE
角色附带,但某些最小化安装可能未赋)
segment_owner
参数填当前用户名即可,填错(如小写或空格)会报
ORA-32034: unsupported use of WITH clause
类似误导性错误 简化版调用(查当前用户下的
ORDERS
):
BEGIN dbms_space.object_space_usage( segment_owner => USER, segment_name => 'ORDERS', segment_type => 'TABLE', used_bytes => :used, alloc_bytes => :alloc ); END;
其中
:used
和
:alloc
是绑定变量,需在支持绑定的客户端(如 SQL*Plus、SQL Developer)中定义并打印。 查视图/索引/LOB 对象大小容易漏掉类型过滤 一张表的空间可能分散在多个 segment 类型里:
TABLE
、
INDEX
、
LOBSEGMENT
、
LOBINDEX
、
MATERIALIZED VIEW
。如果只查
segment_type = 'TABLE'
,会严重低估总占用。 实操建议: 先看全貌:
SELECT segment_type, COUNT(*) FROM user_segments GROUP BY segment_type;
对含 CLOB/BLOB 的表,务必补查:
WHERE segment_name LIKE 'SYS_LOB%' OR segment_name LIKE 'SYS_IL%'
(系统生成的 LOB 段名有固定前缀) 物化视图日志(
MVIEW LOG
)也会产生
TABLE
类型 segment,但名字带
RUPD$_
前缀,容易被忽略 最简汇总语句(含常见类型):
SELECT segment_type, SUM(bytes)/1024/1024 AS mb FROM user_segments WHERE segment_name IN ( SELECT table_name FROM user_tables UNION SELECT index_name FROM user_indexes UNION SELECT segment_name FROM user_lobs ) GROUP BY segment_type;
真实环境里,LOB 和索引常占表总大小的 30%–200%,跳过它们等于只看了冰山一角。

相关文章