ITPub博客

首页 > 数据库 > Oracle > Clustering Factor(聚簇因子)

Clustering Factor(聚簇因子)

原创 Oracle 作者:wanyahai 时间:2014-03-23 13:17:04 0 删除 编辑
聚簇因子是索引与它所基于的表相比较而得出的有序性度量,它用来检查在索引访问之后执行的表查找的成本(将聚簇因子与选择性(selectivity)相乘即可得到该操作的成本)。聚簇因子记录在扫描索引时将读取的块数量。如果使用的索引具有较大的聚簇因子,则必须访问更多的表数据库才可以获得每个索引块中的行(因为临近行位于不同的块中)。如果聚簇因子接近于表中的块数量,则表示索引适当排序;但是,如果聚簇因子接近于表中的行数量,则表示索引没有适当排序。
Clustering_Factor列位于USER_INDEXES视图中,该列反映了数据相对于以索引的列是否显得有序。如果Clustering_Factor列的值接近于索引中的树叶块(leaf block)的数目,表中的数据即使有序的。索引的树叶块存储索引值以及它们指向的ROWID。
如果这个统计数据不能真实反映出索引的真实情况,那么可能会造成优化器错误的选择执行计划。另外如果某表上的大多数访问是按照某个索引做索引扫描,那么将该表的数据按照索引字段的顺序重新组织,可以提高该表的访问性能。
聚簇因子的计算
(1)扫描一个索引。
(2)比较某行的ROWID和前一行(基于索引位置的前一行)的ROWID,如果这两个ROWID不属于同一个数据块,那么集群因子增加1.
(3)整个索引扫描完毕后,就得到了该索引的集群因子。
通过下面的例子来验证Clustering Factor的计算方法:

建表t(x,y,z),分别在建立索引ind_x,ind_y。

点击(此处)折叠或打开

  1. SQL> drop table t;

  2. Table dropped.

  3. SQL> create table t(x int,y int,z varchar2(4000) );

  4. SQL> create index ind_x on t(x);

  5. Index created.

  6. SQL> create index ind_y on t(y);

  7. Index created.
插入数据:

点击(此处)折叠或打开

  1. SQL> insert into t
  2.   2 select rownum,dbms_random.value(1,1999999),rpad('*',3500,'*')
  3.   3 from emp;

  4. 14 rows created.

  5. SQL> commit;

  6. Commit complete.
查看Clustering Factor
通过user_indexes查询出Clustering Factor数量。

点击(此处)折叠或打开

  1. SQL> exec dbms_stats.gather_table_stats(user,'T',cascade=>true);

  2. PL/SQL procedure successfully completed.

  3. SQL> select index_name,clustering_factor
  4.   2 from user_indexes
  5.   3 where table_name='T';

  6. INDEX_NAME CLUSTERING_FACTOR
  7. ------------------------------ -----------------
  8. IND_X 7
  9. IND_Y 14
查看表中数据块的分布情况

点击(此处)折叠或打开

  1. SQL> select x,y,rowid,dbms_rowid.rowid_block_number(rowid) blockno
  2.   2 from t;

  3.          X Y ROWID BLOCKNO
  4. ---------- ---------- ------------------ ----------
  5.          1 397533 AAACqLAAEAAAACUAAA 148
  6.          2 100934 AAACqLAAEAAAACUAAB 148
  7.          5 1844900 AAACqLAAEAAAACVAAA 149
  8.          6 864162 AAACqLAAEAAAACVAAB 149
  9.          7 89650 AAACqLAAEAAAACWAAA 150
  10.          8 486379 AAACqLAAEAAAACWAAB 150
  11.          9 237937 AAACqLAAEAAAACXAAA 151
  12.         10 23569 AAACqLAAEAAAACXAAB 151
  13.          3 696813 AAACqLAAEAAAACYAAA 152
  14.          4 227443 AAACqLAAEAAAACYAAB 152
  15.         13 1205584 AAACqLAAEAAAADpAAA 233

  16.          X Y ROWID BLOCKNO
  17. ---------- ---------- ------------------ ----------
  18.         14 684005 AAACqLAAEAAAADpAAB 233
  19.         11 108105 AAACqLAAEAAAADwAAA 240
  20.         12 1701986 AAACqLAAEAAAADwAAB 240

  21. 14 rows selected.
1,2在索引中顺序相邻,表中数据也在同一块,所以不产生Clustering Factor, 2,3产生。同理4,5;6,7;8,9;10,11;12,13都产生Clustering Factor一共7个Clustering Factor。
对y列排序后进行分析:产生的Clustering Factor确实应该为14。

点击(此处)折叠或打开

  1. SQL> select y,dbms_rowid.rowid_block_number(rowid) blockbno
  2.   2 from t
  3.   3 order by y;

  4.          Y BLOCKBNO
  5. ---------- ----------
  6.      23569 151
  7.      89650 150
  8.     100934 148
  9.     108105 240
  10.     227443 152
  11.     237937 151
  12.     397533 148
  13.     486379 150
  14.     684005 233
  15.     696813 152
  16.     864162 149

  17.          Y BLOCKBNO
  18. ---------- ----------
  19.    1205584 233
  20.    1701986 240
  21.    1844900 149

  22. 14 rows selected.

如何降低聚簇因子:
通过Clustering Factor的计算方法不难发现,如果真相降低Clustering Factor只能rebuild table,而不是rebuild index。
即使我们通过rebuild table的对某列进行有序的排列,使该列索引的Clustering Factor降低,但是与此同时其它的索引的Clustering Factor可能会增加。其实大多数情况下,我们不用太在于CF值,CF值过高也不一定代表index性能不好。单纯为了降低Clustering Factor而对表进行重建也是不可取的尽管rebulid table是降低Clustering Factor的唯一途径。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29173997/viewspace-1127626/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2013-11-17

  • 博文量
    39
  • 访问量
    72852