2013-03-22 57 views

回答

28

大多数企业数据库(包括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个具有ACTIVE的issue_status,10,000个具有QUEUED的issue_status,并且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' 

它会更有效地执行表扫描。

收集统计信息允许查询计划随着数据量和数据分布的变化随时间变化。当您第一次安装问题跟踪器时,您将遇到很少的COMPLETED问题以及更多ACTIVE和QUEUED问题。随着时间的推移,完成问题的数量上升得更快。随着您在表格中获得更多行并且处于不同状态的那些行的相对部分发生更改,查询计划将发生变化,因此在理想的情况下,您始终可以获得最有效的计划。

+0

非常感谢贾斯汀,这很有道理。 – Manth 2013-03-25 16:43:04

+0

看了很多关于GATHER_TABLE_STATS的文档,这个很好解释。感谢分享你的想法! – 2016-06-29 16:15:36