如何获取Oracle数据库中发生的插入/更新次数?

时间:2011-07-14 21:14:05

标签: oracle oracle10g storage oracle11g

如何获取一段时间内Oracle数据库中发生的插入/更新总数?

1 个答案:

答案 0 :(得分:9)

假设您已配置AWR以保留所有SQL语句的数据(默认情况下,如果STATISTICS_LEVEL为'TYPICAL'且前100名,则仅按CPU保留前30名,已用时间等如果STATISTICS_LEVEL是'ALL'),可以通过类似

的方式
BEGIN
  dbms_workload_repository.modify_snapshot_settings (
    topnsql => 'MAXIMUM'
  );
END;

并且假设在快照捕获它们之前SQL语句没有从缓存中老化,您可以使用AWR表来实现其中一些。

您可以收集执行INSERT语句的次数以及执行UPDATE语句的次数

SELECT sum( stat.executions_delta ) insert_executions
  FROM dba_hist_sqlstat stat 
       JOIN dba_hist_sqltext txt ON (stat.sql_id = txt.sql_id )
       JOIN dba_hist_snapshot snap ON (stat.snap_id = snap.snap_id)
 WHERE snap.begin_interval_time BETWEEN <<start time>> AND <<end time>>
   AND txt.command_type = 2;

SELECT sum( stat.executions_delta ) update_executions
  FROM dba_hist_sqlstat stat 
       JOIN dba_hist_sqltext txt ON (stat.sql_id = txt.sql_id )
       JOIN dba_hist_snapshot snap ON (stat.snap_id = snap.snap_id)
 WHERE snap.begin_interval_time BETWEEN <<start time>> AND <<end time>>
   AND txt.command_type = 6;

请注意,这些查询包括应用程序发出的语句和Oracle在后台发出的语句。如果要过滤掉某些SQL语句,可以添加其他条件。

同样,您可以获得不同INSERT和UPDATE语句的总数

SELECT count( distinct stat.sql_id ) distinct_insert_stmts
  FROM dba_hist_sqlstat stat 
       JOIN dba_hist_sqltext txt ON (stat.sql_id = txt.sql_id )
       JOIN dba_hist_snapshot snap ON (stat.snap_id = snap.snap_id)
 WHERE snap.begin_interval_time BETWEEN <<start time>> AND <<end time>>
   AND txt.command_type = 2;


SELECT count( distinct stat.sql_id ) distinct_update_stmts
  FROM dba_hist_sqlstat stat 
       JOIN dba_hist_sqltext txt ON (stat.sql_id = txt.sql_id )
       JOIN dba_hist_snapshot snap ON (stat.snap_id = snap.snap_id)
 WHERE snap.begin_interval_time BETWEEN <<start time>> AND <<end time>>
   AND txt.command_type = 6;
但是,Oracle不会跟踪在给定时间间隔内插入或更新的行数。因此,您将无法从AWR获取该信息。您可以获得的最接近的是尝试利用Oracle所做的监控来确定统计信息是否过时。假设为每个表启用MONITORING(默认情况下为11g,我认为默认情况下为10g),即

ALTER TABLE table_name
  MONITORING;

Oracle会定期将每个表插入,更新和删除的大致行数刷新到SYS.DBA_TAB_MODIFICATIONS表。但这只会显示活动,因为统计数据是在表格上收集的,而不是特定时间间隔内的活动。但是,您可以尝试编写一个定期将此数据捕获到您自己的表中的进程并报告该进程。

如果您指示Oracle将监视信息从内存刷新到磁盘(否则会有几个小时的延迟)

BEGIN
  dbms_stats.flush_database_monitoring_info;
END;

您可以获得自上次收集统计信息以来每个表中已更改的行数的近似计数

SELECT table_owner,
       table_name,
       inserts,
       updates,
       deletes
  FROM sys.dba_tab_modifications