database - 为什么 Oracle 使用 DBMS_STATS.GATHER_TABLE_STATS?

标签 database performance oracle

<分区>

我找到了解释 Oracle 使用这些来进行性能调优等的文档,但不太了解它实际上做了什么。

谁能用简单的语言和非常基本的例子向我解释一下?

最佳答案

大多数企业数据库,包括 Oracle,都使用基于成本的优化器来为给定的 SQL 语句确定合适的查询计划。这意味着优化器使用有关数据的信息来确定如何执行查询而不是依赖规则(这是旧的基于规则的优化器所做的)。

例如,想象一个简单的错误跟踪应用程序的表

CREATE TABLE issues (
  issue_id number primary key,
  issue_text clob,
  issue_status varchar2(10)
);

CREATE INDEX idx_issue_status
    ON issues( issue_status );

如果我是一家大公司,这张表中可能有 100 万行。其中,100 个的 issue_status 为 ACTIVE,10,000 个的 issue_status 为 QUEUED,989,900 个的状态为 COMPLETE。如果我想对表运行查询以查找我的事件问题

SELECT *
  FROM issues
 WHERE issue_status = 'ACTIVE'

优化器有一个选择。它可以使用 issue_status 上的索引,然后在表中为索引中匹配的每一行执行单行查找,或者它可以对 issues 执行表扫描> 表。哪个计划更有效将取决于表中的数据。如果 Oracle 希望查询返回表中的一小部分数据,那么使用索引会更有效。如果 Oracle 希望查询返回表中大部分数据,则表扫描会更有效。

DBMS_STATS.GATHER_TABLE_STATS 是收集允许 Oracle 做出此决定的统计数据。它告诉 Oracle 表中大约有 100 万行,issue_status 列有 3 个不同的值,并且数据分布不均匀。因此 Oracle 知道使用索引进行查询以查找所有事件问题。但它也知道,当你转身试图寻找所有已关闭的问题时

SELECT *
  FROM issues
 WHERE issue_status = 'CLOSED'

进行表扫描会更有效率。

收集统计信息允许查询计划随着数据量和数据分布的变化而变化。当您第一次安装问题跟踪器时,您将遇到很少的已完成问题和更多的事件和已排队的问题。随着时间的推移,已完成问题的数量增加得更快。随着表中的行越来越多,并且处于各种状态的这些行的相对比例发生变化,查询计划也会发生变化,因此在理想情况下,您始终可以获得最有效的计划。

关于database - 为什么 Oracle 使用 DBMS_STATS.GATHER_TABLE_STATS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15575422/

相关文章:

SQL Server表设计;一个带有类型列的表与多个表

node.js - 无法在 Angular 2 中使用 TypeORM,未找到模块 MySQL

java - 两个 Derby 数据库可以在同一主机上运行吗?

c - 如何测量一小段 C/汇编代码的速度?

oracle - 条件触发

java - 在Java中将字符串日期转换为sql日期格式

mysql - 处理关系数据库中记录的可选字段

java - 单例模式的每个 Gem 内存不足

android - Android 中麦克风阈值监控的最低电池消耗

sql - 使用 EAV 表连接/旋转项目