SQL调优之列值的集簇因子研究

列值的选择性、集簇和柱状图

切记,优化器了解表中列数据的许多重要特征,最显著的是列值的选择性和列的集簇因子。

例如,以下我们看到一个使用列值来形成结果集的查询:

select

  customer_name

from

  customer

where

  customer_state = 'Rhode Island';

在此示例中,选择使用索引还是全表扫描受到罗得岛客户比例的影响。如果罗得岛客户的比例非常小 ,并且数值集簇在数据块中,则对于此查询而言索引扫描可能是最快的执行计划。

许多 Oracle 开发人员对于当他们只检索很少量的行时优化器选择全表扫描而感到困惑,而没有意识 到优化器考虑了表中列值的集簇。

Oracle 在 dba_indexes 视图中提供一个名为 clustering_factor 的列,通知优化器关于表的行与索 引的同步情况。当集簇因子接近数据块的数量时,表的行与索引同步。

列值的选择性、db_block_size、avg_row_len 以及集合基数全都协同工作,帮助优化器决定是使用索 引还是使用全表扫描。如果数据列具有高度的选择性和低的 clustering_factor,则索引扫描通常是最快 的执行方法(参见图 2)。

如果多数 SQL 引用了具有高 clustering_factor、大 db_block_size 和小 avg_row_len 的列,则 DBA 有时会周期性地对表的行进行重排序或使用单表集簇来维持行的顺序。这种方法将所有相邻的行放置 在同一数据块中,消除了全表扫描,使查询速度的增加高达 30 倍。

相反,高 clustering_factor 的数值达到表中的行数 (num_rows),表明这些行的顺序与索引中的顺 序不同,索引范围扫描将会需要额外的 I/O。由于 clustering_factor 达到表中的行数,这些行与索引 不同步。

但是,即使列具有高度的选择性,高 clustering_factor 和小 avg_row_len 也会表示列值在表中随 机分布,而获取这些行需要额外的 I/O。在此情况下,索引范围扫描会导致大量不必要的 I/O(参见图 3 );全表扫描则会高效得多。

总而言之,clustering_factor、db_block_size 和 avg_row_len 全都影响优化器有关执行全表扫描 或是索引范围扫描的决策,理解优化器如何使用这些统计信息非常重要。

我们已经注意到,每个新版本的优化器都有改进,并且 Oracle Database 10g 提供的最新增强特性在 确定执行计划时会考虑外部的影响。Oracle 称此特性为外部成本核算,并包括对 CPU 和 I/O 成本的评 估。

以下例子来说明列值的集簇因子对执行计划产生的影响:

1、 搭建环境  

SQL> insert into test select * from emp;

14 rows created.

Commit complete.  

2、分析表

SQL> analyze table test compute statistics;

Table analyzed.

3、查看列值的集簇因子:

select t.table_name,t.NUM_ROWS,t.BLOCKS,t.AVG_ROW_LEN,i.index_name,i.CLUSTERING_FACTOR

from dba_tables t,dba_indexes i

where t.table_name=i.table_name

and t.owner='SCOTT'

and t.table_name='TEST';

TABLE_NAME   NUM_ROWS     BLOCKS AVG_ROW_LEN INDEX_NAME CLUSTERING_FACTOR

---------- ---------- ---------- ----------- ---------- -----------------

TEST            14               1       32      TEST_ENAME              1




转载请注明:http://www.xcqg58.com/jbjj/jbjj/4.html