这个问题通常需要对 v$segment_statistics 中的信息进行一些快照,除非广泛的审计是可行的,对于繁忙的数据库通常不是这种情况。特别是,检查“逻辑读取”和“数据库块更改”统计数据中的更改,以查看对表的读取和/或写入的证据。但是,统计信息收集可能会放弃这种方法来排除应用程序读取,除非 dbms_stats 与“GATHER AUTO”或“GATHER STALE”选项一起使用(因为统计信息收集将生成逻辑读取。)这些选项只收集那些表的统计信息自上次收集统计信息以来发生了大量更改,因此未获得插入、更新或删除的表将永远不会收集统计信息。 (这假设 statistics_level 参数至少设置为“典型”,这是默认设置。)
Oracle 11g 中的默认统计信息收集作业确实使用“GATHER AUTO”,如 here 所述。您可以通过以下查询确认它是否正在使用:
SQL> select client_name, status from dba_autotask_client;
CLIENT_NAME STATUS
------------------------------------ --------
auto optimizer stats collection ENABLED
auto space advisor ENABLED
sql tuning advisor ENABLED
如果默认的统计数据收集正在进行,而所有表的手动统计数据收集没有发生,您可以从检查 last_analyze 时间开始:
select table_name, last_analyzed from all_tables
where owner = 'HR' order by last_analyzed;
怀疑未使用的表可能是那些 last_analyzed 值较旧的表。如果只关注写入,则可以检查 all_tab_modifications:
select table_name, inserts+updates+deletes as change_count, timestamp
from all_tab_modifications where table_owner = 'HR';
如果需要检查读取,则 AWR(需要诊断包许可证)在 dba_hist_seg_stat 视图中具有段信息的快照。如果没有诊断包,Statspack 可以将段信息填充到统计级别 7 或更高级别的 stats$seg_stat 中。 (More on Statspack levels.) 但是,这两者都可以证明表正在被使用,但不能证明表未被使用。原因是这两种工具都只选择了有限数量的“顶部”片段。
要获得明确的答案,您可能需要制作自己的信息快照。一个非常简单的方法可以从创建这样的表开始:
create table my_segstat as select sysdate as snap_date,
object_name, object_type, statistic_name, value
from v$segment_statistics
where owner = 'HR'
and statistic_name in ('logical reads', 'db block changes') ;
然后设置一个作业来定期添加信息的快照,查询如下:
insert into my_segstat as select sysdate as snap_date,
object_name, object_type, statistic_name, value
from v$segment_statistics
where owner = 'HR'
and statistic_name in ('logical reads', 'db block changes') ;
稍后,可以根据这样的查询分析数据:
select snap_date, object_name, statistic_name,
value - lag(value) over (partition by object_name, statistic_name
order by snap_date) as delta
from my_segstat;
当然,读取或写入应该是“未使用”的表的其他内容也可能会影响这种分析方法。