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

Posted

技术标签:

【中文标题】Oracle 数据库统计信息应该多久运行一次?【英文标题】:How often should Oracle database statistics be run? 【发布时间】:2010-09-09 21:41:16 【问题描述】:

根据您的经验,我们的开发团队最近发现,我们的生产箱已经超过 2 1/2 个月没有运行统计数据。这对我来说听起来很长一段时间,但我不是 DBA。

【问题讨论】:

【参考方案1】:

由于 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;

【讨论】:

【参考方案2】:

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

如果一个表从 1 行变为 200 行,这是一个重大变化。当一个表从 100,000 行变为 150,000 行时,这并不是一个非常显着的变化。当一个表从 1000 行在常用查询的 X 列中具有相同值的行变为 1000 行在 X 列中具有几乎唯一的值时,这是一个显着的变化。

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

【讨论】:

【参考方案3】:

在我的上一份工作中,我们每周运行一次统计数据。如果我没记错的话,我们将它们安排在星期四晚上,而在星期五,DBA 非常小心地监控运行时间最长的查询是否有任何意外情况。 (选择星期五是因为它通常是在代码发布之后,并且往往是流量相当低的一天。)当他们看到一个错误的查询时,他们会找到一个更好的查询计划并保存它,这样它就不会再次意外更改. (Oracle 有工具可以自动为您执行此操作,您告诉它要优化的查询,它就会这样做。)

许多组织避免运行统计数据是因为担心会意外弹出错误的查询计划。但这通常意味着他们的查询计划会随着时间的推移变得越来越糟糕。当他们运行统计数据时,他们会遇到许多问题。由此产生的解决这些问题的争夺证实了他们对运行统计数据的危险的担忧。但是,如果他们定期进行统计,按应有的方式使用监控工具,并在出现问题时解决问题,那么他们就不会那么头疼了,也不会一下子遇到所有问题。

【讨论】:

【参考方案4】:

您使用的是哪个 Oracle 版本?检查此页面,它指的是 Oracle 10:

http://www.acs.ilstu.edu/docs/Oracle/server.101/b10752/stats.htm

上面写着:

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

【讨论】:

【参考方案5】:

当我管理一个由 Oracle 支持的大型多用户计划系统时,我们的 DBA 每周都有一项工作是收集统计数据。此外,当我们推出可能影响统计数据或受统计数据影响的重大更改时,我们会强制工作超出周期以赶上进度。

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

确保平衡新的统计信息导致查询计划发生不良更改的风险与陈旧的统计信息本身可能导致查询计划更改的风险。

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

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

通常不建议如此频繁地收集整个数据库的统计信息,除非您有充分的理由这样做,例如数据库上频繁发生批量插入或大数据更改。 以这种频率收集数据库统计信息可能会将查询执行计划更改为新的不良执行计划,这可能会花费您很多时间尝试调整受新不良计划影响的每个查询,这就是为什么您应该测试收集的影响测试数据库上的新统计信息,或者如果您没有时间或人力,至少您应该通过在收集新统计信息之前备份原始统计信息来保留备用计划,这样万一您收集了新的统计信息,然后查询没有按预期执行,您可以轻松恢复原始统计信息。

有一个非常有用的脚本可以帮助您备份原始统计数据并收集新的统计数据,并为您提供 SQL 命令,您可以使用它来恢复原始静态数据,以防在收集新的统计数据后事情没有按预期进行。您可以在此链接中找到脚本: http://dba-tips.blogspot.com/2014/09/script-to-ease-gathering-statistics-on.html

【讨论】:

以上是关于Oracle 数据库统计信息应该多久运行一次?的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE索引失效,更新统计信息

oracle收集统计信息无法开并行

oracle中的统计信息问题

急:oracle 30分钟统计一次数据怎么做

急:oracle 30分钟统计一次数据怎么做......?

数据库优化之统计分析实战篇