【问题标题】:Find all tables which are not used in a given period in Oracle在Oracle中查找在给定时间段内未使用的所有表
【发布时间】:2018-05-26 22:06:15
【问题描述】:

试图找到一个 SQL 查询,它可以列出在 oracle 中给定时间段内未使用的所有表。

以下查询返回所有者的所有表:

select tablespace_name, table_name
from ALL_TABLES
where owner ='HP';

我执行以下查询以获取有关表读写的一些统计信息,不幸的是它返回错误表未找到:

SELECT *
FROM v$segment_statistics
WHERE owner = 'HP';

有什么方法可以根据范围在表格中包含日期因子过滤器?

【问题讨论】:

  • 您需要对该视图的选择权限,或为此授予“选择任何字典”权限
  • 如果您有诊断和调优许可证,您可以从DBA_HIST_SEG_STAT 视图中获取信息。
  • @access_granted now 已授予权限,但该表没有任何日期相关信息

标签: sql oracle oracle11g


【解决方案1】:

“在给定时间段内未使用的所有表”是指任何用途吗?请记住,有直接用法:SELECT、INSERT、UPDATE、DELETE。还有间接使用,例如外键的强制执行。间接使用会很困难。另请注意,某些对象可能仅在季节性使用(例如,如果您的应用程序具有季度或年终报告等业务周期)。

所以这是一个审计问题。您可以使用 Oracle 的标准 AUDIT 功能找到此信息。默认情况下不会打开它,因为记录 DML 活动会产生开销。如果您为所有表启用它,则每次针对表发出 SELECT 时的日志记录开销可能会很明显。所以请谨慎使用。

AUDIT SELECT TABLE, UPDATE TABLE, INSERT TABLE, DELETE TABLE; 

Find out more

审核将记录每次在表上发生 DML 操作。这显然比您需要的信息更多。但这就是存在的。

您提到了使用v$segment_statistics 的可能性。这是动态性能视图之一,默认情况下不会授予普通用户,而是询问您的 DBA。正如您所注意到的,它只是统计的运行计数,没有日期或时间戳列。如果您的组织许可 Diagnostic pack,您将在 AWR 视图 DBA_HIST_SEG_STATS 中找到这些统计信息的历史记录。

如果您仍然使用 AWR,那么利用这些数据来跟踪正在使用的表是一件简单的事情。但是,如果您没有必要的许可证,则必须维护自己的 v$segment_statistics 历史记录并自己检查增量。这只需要是从后台作业运行的日常任务。


这一切似乎都相当复杂,因为它表面上应该是一项简单的任务。 Oracle 似乎认为我们应该很好地了解我们模式中的所有表。但遗憾的是,根据我的经验,开发人员更愿意创建表而不是放弃它们。因此,存在一些遗留系统,它们的模式过度生长,并且没有简单的方法来进行影响分析,因为太多的 SQL 嵌入在外部 DAO 装置中。

【讨论】:

    【解决方案2】:

    这个问题通常需要对 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;
    

    当然,读取或写入应该是“未使用”的表的其他内容也可能会影响这种分析方法。

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 2018-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 2011-02-19
      相关资源
      最近更新 更多