database - Oracle - 创建索引或添加列后是否需要计算统计信息?

标签 database oracle statistics

我们在生产环境中使用 Oracle 10.2.0.5 数据库。

优化器处于“基于成本”模式。

我们是否需要在以下之后计算统计信息(DBMS_STATS 包):

  • 创建新索引
  • 添加一列
  • 创建一个新表

?

谢谢

最佳答案

没有简短的答案。这完全取决于您的数据以及您如何使用它。以下是一些需要考虑的事项:

正如@NullUserException 所指出的,统计数据是自动收集的,通常是每晚。这通常就足够了;在大多数 (OLTP) 环境中,如果您只是添加新对象,在自动收集统计信息之前它们不会包含大量数据。计划不会那么糟糕,如果对象是新的,它们可能不会立即被大量使用。

  • 创建新索引 - 编号 "Oracle Database now automatically collects statistics during index creation and rebuild".
  • 添加一列 - 也许吧。如果该列将用于连接和谓词,您可能需要它的统计信息。如果它只是用于存储和显示数据,它不会真正影响任何计划。但是,如果新列占用大量空间,它可能会显着改变平均行长度、 block 数、行链接等,优化器应该知道这一点。
  • 创建一个新表 - 可能。 Oracle 能够通过 dynamic sampling 补偿缺失的统计信息,尽管这通常不够好。特别是如果新表有很多数据;糟糕的统计数据几乎总是会导致低估基数,这会在您需要散列连接时导致嵌套循环。此外,即使表数据没有更改,您可能需要再次收集统计信息以启用直方图。默认情况下,Oracle 为偏斜数据创建直方图,但如果这些列未用作谓词,则不会启用这些直方图。 (因此这也适用于添加新列)。如果您删除并重新创建一个表,即使使用相同的名称,Oracle 也不会维护该列的任何使用数据,并且不知道您需要某些列的直方图。

收集优化器统计数据比大多数人意识到的要困难得多。在我目前的工作中,我们的大部分性能问题最终都是因为糟糕的统计数据。如果您想为您的系统制定计划,您应该阅读 Managing Optimizer Statistics chapter .


更新:

无需为空对象收集统计信息;动态采样的工作速度与从数据字典中读取统计数据一样快。 (基于硬解析大量有和没有统计数据的查询的快速测试。)如果禁用动态采样,那么可能会出现一些奇怪的情况,即 Oracle 默认值导致计划不准确,你最好使用统计数据一张空 table 。

我认为 Oracle 在创建时自动收集索引统计信息的原因是它不会额外花费太多。当你创建一个索引时,你必须读取表中的所有 block ,因此 Oracle 不妨同时计算级别数、 block 数、键数等。

表统计可能更复杂,可能需要多次传递数据。与可用作 create-table-as-select 的一部分的任意 SQL 相比,创建索引相对简单。获取这些任意 SQL 语句并将它们转换为同时返回收集统计信息所需的信息的查询可能是不可能的,也不是高效的。

当然,为空表收集统计信息不会花费任何额外费用。但它也不会给您带来任何好处,它只会误导任何查看 USER_TABLES.LAST_ANALYZED 的人 - 该表似乎已被分析,但没有任何有意义的数据。

关于database - Oracle - 创建索引或添加列后是否需要计算统计信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7289319/

相关文章:

database - 如何在 Liferay 中使用默认数据填充数据模型?

mysql - 修改列的最简单方法?

mysql - 可以在 mysql 中创建的数据库的最大限制?

Oracle 编码标准特性实现

python - Python 中每一行的两个样本 t 检验

database - 我如何使用表单将数据插入到我的 H2 数据库中

oracle - 使用 Oracle JDBC 驱动程序隐式缓存功能

sql - Oracle 计数 (*) 花费太多时间

python - 通过Python处理loess函数中的rpy2/R问题?

elasticsearch - 按比例计算修整平均值