作为一名Oracle DBA,我经常需要分析用户表空间使用情况。这个脚本是我在实际工作中总结出来的高效工具,它能自动生成SCOTT用户(或其他指定用户)的表大小统计报告。相比手动查询,这个脚本提供了更系统化的分析维度,特别适合存储容量规划和性能优化场景。
脚本的核心价值在于三点:一是自动化输出标准化报告,节省手工整理时间;二是提供多维度分析视角,从整体到局部全面掌握存储分布;三是可直接用于审计和决策,数据准确且可追溯。下面我将详细拆解这个脚本的实现原理和使用技巧。
脚本设计的精妙之处在于它的三层分析结构:
sql复制SELECT
'SCOTT' AS OWNER,
COUNT(*) AS TABLE_COUNT,
ROUND(SUM(BYTES)/1024/1024, 2) AS TOTAL_SIZE_MB,
ROUND(SUM(BYTES)/1024/1024/1024, 2) AS TOTAL_SIZE_GB
FROM
DBA_SEGMENTS
WHERE
OWNER = 'SCOTT'
AND SEGMENT_TYPE = 'TABLE';
sql复制SELECT
TABLESPACE_NAME,
COUNT(*) AS TABLE_COUNT,
ROUND(SUM(BYTES)/1024/1024, 2) AS TOTAL_SIZE_MB,
ROUND(SUM(BYTES)/1024/1024/1024, 2) AS TOTAL_SIZE_GB,
ROUND((SUM(BYTES)/ (SELECT SUM(BYTES) FROM DBA_SEGMENTS...)) *100,2) AS RATIO_PERCENT
FROM
DBA_SEGMENTS
WHERE...
GROUP BY
TABLESPACE_NAME
sql复制SELECT
ROWNUM AS RANK,
SEGMENT_NAME AS TABLE_NAME,
TABLESPACE_NAME,
ROUND(BYTES/1024/1024, 2) AS TABLE_SIZE_MB,
ROUND(BYTES/1024/1024/1024, 2) AS TABLE_SIZE_GB,
ROUND((BYTES/ (SELECT SUM(BYTES) FROM...)) *100,2) AS RATIO_PERCENT
FROM
DBA_SEGMENTS
WHERE...
ORDER BY
BYTES DESC
提示:比例计算(RATIO_PERCENT)是这个脚本的亮点,它能直观显示每张表或表空间的相对重要性,帮助快速定位关键问题点。
DBA_SEGMENTS视图的使用:
SEGMENT_TYPE = 'TABLE'过滤出普通表(排除索引等)存储单位转换技巧:
/1024/1024将字节转换为MB/1024/1024/1024将字节转换为GB动态排名实现:
权限检查:
SELECT ANY DICTIONARY或至少SELECT ON DBA_SEGMENTS权限sql复制SELECT * FROM SESSION_PRIVS WHERE PRIVILEGE LIKE '%DBA%';
脚本定制:
SPOOL E:/SCOTT_TABLE_SIZE_REPORT.txt中的文件路径执行环境确认:
sql复制-- 连接到SQL*Plus
sqlplus / as sysdba
-- 执行脚本
@generate_table_report.sql
高级执行选项:
执行结果示例:
code复制==============================================
SCOTT用户表大小统计报告
生成时间:2023-08-20 14:30:22
==============================================
【1. 整体汇总】
----------------------------------------------
OWNER TABLE_COUNT TOTAL_SIZE_MB TOTAL_SIZE_GB
------- ----------- ------------- -------------
SCOTT 142 2456.78 2.40
【2. 按表空间分组统计】
----------------------------------------------
TABLESPACE_NAME TABLE_COUNT TOTAL_SIZE_MB TOTAL_SIZE_GB RATIO_PERCENT
-------------------- ----------- ------------- ------------- -------------
USERS 85 1802.45 1.76 73.38
SYSAUX 57 654.33 0.64 26.62
【3. 单表大小明细(TOP 50)】
----------------------------------------------
RANK TABLE_NAME TABLESPACE_NAME TABLE_SIZE_MB TABLE_SIZE_GB RATIO_PERCENT
---- ----------------------------------- -------------------- ------------- ------------- -------------
1 BIG_TABLE USERS 1024.00 1.00 41.68
2 HISTORY_DATA USERS 512.00 0.50 20.84
...
存储规划场景:
性能优化场景:
故障排查场景:
原脚本基础上添加分区表分析功能:
sql复制PROMPT 【4. 分区表明细】
PROMPT ----------------------------------------------
SELECT
tp.TABLE_NAME,
tp.PARTITION_NAME,
tp.TABLESPACE_NAME,
ROUND(s.BYTES / 1024 / 1024, 2) AS PARTITION_SIZE_MB
FROM
DBA_TAB_PARTITIONS tp
LEFT JOIN DBA_SEGMENTS s ON s.OWNER = tp.TABLE_OWNER
AND s.SEGMENT_NAME = tp.TABLE_NAME
AND s.SEGMENT_TYPE = 'TABLE PARTITION'
AND s.PARTITION_NAME = tp.PARTITION_NAME
WHERE
tp.TABLE_OWNER = 'SCOTT';
创建历史记录表并修改脚本实现自动归档:
sql复制-- 创建历史记录表
CREATE TABLE TABLE_SIZE_HISTORY (
REPORT_DATE DATE,
OWNER VARCHAR2(30),
TABLE_COUNT NUMBER,
TOTAL_SIZE_MB NUMBER,
TOTAL_SIZE_GB NUMBER
);
-- 在脚本中添加归档语句
INSERT INTO TABLE_SIZE_HISTORY
SELECT
SYSDATE,
'SCOTT',
COUNT(*),
ROUND(SUM(BYTES)/1024/1024, 2),
ROUND(SUM(BYTES)/1024/1024/1024, 2)
FROM
DBA_SEGMENTS
WHERE
OWNER = 'SCOTT'
AND SEGMENT_TYPE = 'TABLE';
COMMIT;
使用SQL*Plus的HTML功能生成更美观的报告:
sql复制SET MARKUP HTML ON
SPOOL E:/SCOTT_TABLE_SIZE_REPORT.html
-- 原有查询语句
SPOOL OFF
SET MARKUP HTML OFF
问题现象:
code复制ORA-00942: 表或视图不存在
解决方案:
确认执行用户是否有DBA权限或至少以下权限:
sql复制GRANT SELECT ON DBA_SEGMENTS TO 用户名;
GRANT SELECT ON DBA_TAB_PARTITIONS TO 用户名;
或者使用SYSDBA角色执行:
sql复制sqlplus / as sysdba
可能原因:
解决方案:
更新统计信息:
sql复制EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT');
精确过滤条件:
sql复制WHERE OWNER = 'SCOTT'
AND SEGMENT_TYPE IN ('TABLE','TABLE PARTITION')
大表处理方案:
分区策略:
sql复制ALTER TABLE BIG_TABLE MODIFY
PARTITION BY RANGE (CREATE_DATE) (
PARTITION P_2022 VALUES LESS THAN (TO_DATE('2023-01-01','YYYY-MM-DD')),
PARTITION P_2023 VALUES LESS THAN (MAXVALUE)
);
压缩存储:
sql复制ALTER TABLE BIG_TABLE MOVE COMPRESS;
清理碎片:
sql复制ALTER TABLE FRAGMENTED_TABLE MOVE TABLESPACE USERS;
最近在一次存储优化项目中,我使用这个脚本发现了几个关键问题:
表空间不均衡分布:
sql复制ALTER TABLE BIG_TABLE MOVE TABLESPACE BIG_DATA;
异常大表识别:
sql复制ALTER TABLE LOG_DATA MODIFY
PARTITION BY RANGE (LOG_DATE) (
PARTITION P_202301 VALUES LESS THAN (TO_DATE('2023-02-01','YYYY-MM-DD')),
...
);
存储增长趋势分析:
这个脚本已经成为我日常运维的必备工具,特别是它的三层分析结构,能快速定位不同层级的问题。建议DBA同行们可以根据自己的需求进一步定制,比如添加索引大小统计、LOB字段分析等功能。