我发现文档解释了 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 万行,列有 3 个不同的值issue_status
,并且数据分布不均匀。因此,Oracle 知道使用索引进行查询以查找所有活动问题。但它也知道,当你转身尝试寻找所有已关闭的问题时
SELECT *
FROM issues
WHERE issue_status = 'CLOSED'
进行表扫描会更有效。
收集统计信息允许查询计划随着数据量和数据分布的变化而随时间变化。当您第一次安装问题跟踪器时,您将遇到很少的 COMPLETED 问题和更多的 ACTIVE 和 QUEUED 问题。随着时间的推移,已完成问题的数量增加得更快。当您在表中获得更多行并且处于各种状态的这些行的相对比例发生变化时,查询计划将发生变化,因此,在理想情况下,您始终可以获得最有效的计划。