Oracle数据库统计信息应该运行多久一次?

23

在你的经验中,Oracle数据库统计信息应该运行多久一次?我们的开发团队最近发现,在我们的生产环境中,统计信息已经超过2个半月没有更新了。对我来说听起来很长,但我不是DBA。

9个回答

22

自 Oracle 11g 起,默认情况下会自动收集统计信息。

在安装 Oracle 数据库时,预定义了两个调度程序窗口:

  • WEEKNIGHT_WINDOW 每周一至周五晚上10点到早上6点启动。
  • WEEKEND_WINDOW 包含整个星期六和星期日。

最后一次收集统计信息是什么时候?

SELECT owner, table_name, last_analyzed FROM all_tables ORDER BY last_analyzed DESC NULLS LAST; --Tables.
SELECT owner, index_name, last_analyzed FROM all_indexes ORDER BY last_analyzed DESC NULLS LAST; -- Indexes.

自动收集统计信息的状态如何?

SELECT * FROM dba_autotask_client WHERE client_name = 'auto optimizer stats collection';

Windows组?

SELECT window_group_name, window_name FROM dba_scheduler_wingroup_members;

窗口计划?

SELECT window_name, start_time, duration FROM dba_autotask_schedule;

手动收集此模式中的数据库统计信息:

EXEC dbms_stats.gather_schema_stats(ownname=>NULL, cascade=>TRUE); -- cascade=>TRUE means include Table Indexes too.

手动收集所有模式下的数据库统计信息!

-- Probably need to CONNECT / AS SYSDBA
EXEC dbms_stats.gather_database_stats;

14

每当数据发生“显著”变化时。

如果一张表从1行变成200行,那就是一个显著的变化。当一张表从100,000行变成150,000行时,并不算是非常显著的变化。当一个表从1000行中常见查询列X的值相同,变成1000行中几乎唯一的列X值时,那就是一个显著的变化。

统计信息存储有关项目数量和相对频率的信息,这些信息可以让它“猜测”有多少行将符合给定条件。当它猜错时,优化器可能会选择一个非常次优的查询计划。


13
在我上一份工作中,我们每周运行一次统计数据。如果我没记错的话,我们会在星期四晚上安排统计任务,在星期五,数据库管理员会非常小心地监控最耗时的查询,以寻找任何意外情况。(星期五被选定是因为通常紧随代码发布之后,并且往往是一个相对低流量的日子)。当他们发现有糟糕的查询时,他们会找到更好的查询计划并保存下来,这样就不会再出现意外变化。(Oracle有自动执行此操作的工具,只需告诉它要优化的查询即可)。
许多组织因担心会出现意外的糟糕查询计划而避免运行统计数据。但这通常意味着他们的查询计划会随着时间的推移变得越来越糟糕。当他们运行统计数据时,他们会遇到许多问题。为解决这些问题而进行的抢救活动确实证实了他们对运行统计数据的危险的担忧。但如果他们定期运行统计数据,按照预期使用监控工具,并在问题出现时进行修复,那么他们将会少些头疼,并且不会一次性遇到所有问题。

5
你使用的Oracle版本是什么?请查看此页面,它提到了Oracle 10:http://www.acs.ilstu.edu/docs/Oracle/server.101/b10752/stats.htm。该页面指出:

收集统计信息的推荐方法是允许Oracle自动收集统计信息。Oracle会自动收集所有数据库对象的统计信息,并在定期维护作业中维护这些统计信息。


2

我曾经管理过一个由Oracle支持的大型多用户规划系统,我们的DBA每周都会有一个任务来收集统计信息。此外,当我们推出可能会影响或受到统计数据影响的重大更改时,我们会强制运行该任务以使事情赶上。


2

在oracle的10g及更高版本中,优化器需要最新的表和索引统计信息来做出“好”的执行计划决策。收集统计信息的频率是一个棘手的问题。这取决于您的应用程序、模式、数据速率和业务实践。一些为与旧版oracle向后兼容而编写的第三方应用程序在使用新的优化器时表现不佳。这些应用程序要求表没有统计信息,以便数据库返回基于规则的执行计划。但通常情况下,Oracle建议对具有过期统计信息的表进行统计信息收集。您可以将表设置为监视并检查它们的状态,并在过期时分析它们。通常这就足够了,但有时候不够。这真的取决于您的数据库。对于我的数据库,我们有一组OLTP表需要每晚收集统计信息以维护性能。其他表每周分析一次。对于我们的大型DW数据库,我们根据需要进行分析,因为这些表太大了,无法定期分析,否则会影响整个数据库的负载和性能。所以正确的答案是,这取决于应用程序、数据变化和业务需求。


1

要平衡新鲜统计数据可能导致查询计划不良变化的风险与陈旧统计数据本身可能导致查询计划变化的风险。

假设您有一个带有ISSUE表和CREATE_DATE列的错误数据库,其中列中的值逐渐单调增加。现在,假设该列上有一个直方图,告诉Oracle该列的值在2008年1月1日至2008年9月17日期间均匀分布。这使优化器可以合理地估计如果您正在查找上周创建的所有问题(即9月7日至13日),将返回多少行。但是,如果应用程序继续使用且未更新统计信息,则此直方图将越来越不准确。因此,优化器会预期随着时间的推移,“上周创建的问题”的查询将变得越来越不准确,并最终可能导致Oracle对查询计划进行负面更改。


0
通常情况下,不建议在整个数据库上频繁收集统计信息,除非你有充分的理由,比如在数据库上经常进行大量插入或大数据更改。在这种频率下收集数据库的统计信息可能会改变查询执行计划为新的较差的执行计划,这可能会花费您很多时间来调整受新的较差计划影响的每个查询,这就是为什么您应该在测试数据库中测试收集新统计信息的影响,或者如果您没有时间或人力,至少应该在收集新统计信息之前备份原始统计信息,以便在收集新统计信息后,如果查询表现不如预期,您可以轻松地恢复原始统计信息。
有一个非常有用的脚本可以帮助您备份原始统计信息并收集新的统计信息,并为您提供SQL命令,以便在收集新统计信息后,如果事情没有按预期进行,可以使用它来恢复原始统计信息。您可以在此链接中找到该脚本:http://dba-tips.blogspot.com/2014/09/script-to-ease-gathering-statistics-on.html

0
在数据仓库类型的系统中,您可以考虑不收集任何统计信息,并依赖于动态采样(将optimizer_dynamic_sampling设置为2级或更高级别)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接