Oracle 11g数据库表分析:查询长期未读数据所需DBA表咨询
嘿,这个问题问到点子上了——要找出Oracle 11g表中哪些数据长期没被读取,得靠几个系统视图组合起来分析,我给你拆解清楚:
1. 表级整体读取统计:DBA_TABLES + DBA_TAB_STATISTICS
这俩视图能先给你表的全局访问情况。DBA_TAB_STATISTICS里的NUM_ROWS_READ是累计读取的行数,LAST_STATS_UPDATE_TIME是统计信息的更新时间,结合这两个字段能判断表在统计周期内有没有被读取过。不过要注意,这些数据依赖于Oracle的自动统计收集(或手动执行DBMS_STATS),如果统计很久没更新,结果会不准。
查询示例:
SELECT table_name, num_rows_read, last_stats_update_time, last_analyzed FROM dba_tab_statistics WHERE owner = '你的用户名称' AND table_name = '目标表名称';
小提示:如果NUM_ROWS_READ在多次查询中数值没变化,说明这段时间内表没有被读取操作命中,但这是表级的统计,没法精准到行。
2. 历史段级访问追踪:DBA_HIST_SEG_STAT
要是你的表是分区表,或者想追溯更长时间的访问记录,AWR(自动工作负载仓库)的DBA_HIST_SEG_STAT视图就很有用。它记录了每个段(表、分区、索引等)的历史访问增量,比如LOGICAL_READS_DELTA(逻辑读增量)、PHYSICAL_READS_DELTA(物理读增量),结合AWR快照的时间范围,能定位到哪些数据段长期没被访问。
分区表查询示例:
SELECT obj.name AS table_name, seg.name AS partition_name, s.begin_interval_time, s.end_interval_time, ss.logical_reads_delta, ss.physical_reads_delta FROM dba_hist_seg_stat ss JOIN dba_hist_snapshot s ON ss.snap_id = s.snap_id JOIN dba_objects obj ON ss.obj# = obj.object_id LEFT JOIN dba_tab_partitions seg ON ss.dataobj# = seg.data_object_id WHERE obj.owner = '你的用户名称' AND obj.object_name = '目标表名称' ORDER BY s.end_interval_time DESC;
注意:AWR默认每小时生成一次快照,保留7天数据。如果需要更长周期的历史,得先确认你的AWR保留配置。
3. 近期实时读取活动排查:V$SESSION + V$SQL
如果想快速确认最近有没有针对目标表的读取操作,可以结合这两个动态性能视图,查询近期执行的SELECT语句:
SELECT s.sid, s.serial#, s.username, sql.sql_text, sql.last_active_time FROM v$session s JOIN v$sql sql ON s.sql_id = sql.sql_id WHERE sql.sql_text LIKE '%目标表名称%' AND sql.sql_text LIKE 'SELECT%' ORDER BY sql.last_active_time DESC;
这个方法只能查到近期的活动,没法追溯更早的历史,但能帮你快速验证当前是否有读取行为。
4. 行级访问监控:DBMS_MONITOR + DBA_TABLE_USAGE
如果需要精确到行的访问记录,Oracle 11g支持表级使用监控。不过这个需要提前开启,没法追溯开启前的历史数据,适合长期追踪:
首先启用监控:
EXEC DBMS_MONITOR.table_usage_enable('你的用户名称', '目标表名称');
之后,通过DBA_TABLE_USAGE查看哪些行被访问过(视图会记录表是否被使用,以及监控的起止时间):
SELECT table_name, monitoring, used, start_monitoring, end_monitoring FROM dba_table_usage WHERE owner = '你的用户名称' AND table_name = '目标表名称';
- 权限要求:查询这些DBA视图需要
SELECT_CATALOG_ROLE权限,或者单独授予SELECT ON对应视图的权限。 - 统计信息准确性:如果
DBA_TAB_STATISTICS的数据很久没更新,建议先手动收集一次统计信息:EXEC DBMS_STATS.gather_table_stats('你的用户名称', '目标表名称'); - AWR可用性:如果你的环境关闭了AWR,
DBA_HIST_SEG_STAT会没有数据,这种情况下只能依赖其他视图。
内容的提问来源于stack exchange,提问作者lukaszFD




