对第1种情况最常见的例子,是以下这样的count语句:
select count(*) from table_name;
在未作分析之前,它使用全表扫描,需要读取1000[假设的]多个数据块(假如一个数据块是8k),做了分析之后,使用的是INDEX (FAST FULL SCAN),可能只需要读取100个数据块。但是如何分析做得不好,也会导致Oracle不使用索引。
一般的估算公式是:FF * (CF + 索引块个数) [备注:toms 说"the formula used by the CBO to compute the cost is blevel + FF * leaf_blocks + FF * clustering_factor"]由此估计出一个查询如果使用某个索引会需要读入的数据块块数。需要读入的数据块越多,则 cost 越大Oracle 也就越可能不选择使用 index.
(全表扫描需要读入的数据块数等于该表的实际数据块数)
FF 则是Oracle 根据分析所做的估计。比如某表有50多万行,其主键的最小值是1,最大值是500000,考虑以下sql 语句:
Select * from table_name where keyid>=1; 和
Select * from table_name where keyid>=500000
这两个表面看上去一样的sql语句,对Oracle而言却有巨大的差别。因为前者的FF是100%,而后者的FF可能只有 1%。如果
它的CF大于实际的数据块数,则Oracle可能会选择完全不同的优化方式。