sys@11GDEMO> show parameter db_block_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
create table cluster_factor_test
(last_name varchar2(30),
first_name char(2000));
使其拥有如下分布的数据,可以插入六条相同的数据,然后再update
sys@11GDEMO> select last_name, dbms_rowid.rowid_block_number(rowid) "block"
from cluster_factor_test; 2
LAST_NAME block
------------------------------ ----------
Arumugam 117402
Cole 117402
Farmer 117402
Brown 117403
Davis 117403
Kevin 117403
6 rows selected.
创建索引,
create index last_name_idx on cluster_factor_test(last_name);
则索引分布如下,
Index Value ROWID
=================================================
Arumugam BLOCK 117402 row 1
Brown BLOCK 117403 row 2
Cole BLOCK 117402 row 3
Davis BLOCK 117403 row 4
Farmer BLOCK 117402 row 5
Kevin BLOCK 117403 row 6
执行,
exec dbms_stats.gather_table_stats(user, 'CLUSTER_FACTOR_TEST', cascade => true);
在统计收集的时候,clustering factor如下计算:
对于每个Index Value,检查rowid,每当块号改变,则其加1。
上面的例子中会使得clustering factor很大,在这样的情况下,优化器会认为,使用此索引的范围扫描的成本要高于其实际情况。
因为优化器认为它需要访问许多不同的块。但实际的情况却是只需要访问两个数据块。
sys@11GDEMO> l
1* select INDEX_NAME, CLUSTERING_FACTOR from user_indexes where INDEX_NAME = '
LAST_NAME_IDX'
sys@11GDEMO> /
INDEX_NAME CLUSTERING_FACTOR
------------------------------ -----------------
LAST_NAME_IDX 6
解决方法之一是,手动设置该索引的clustering factor统计信息,以告诉优优器真实的情况,当然需要测试设置为多少,以帮助
优化器有更好的统计数据使其作出更好的选择。在这里我们设置clstfct为2
sys@11GDEMO> execute DBMS_STATS.SET_INDEX_STATS(user, 'LAST_NAME_IDX', clstfct=>
2 );
PL/SQL procedure successfully completed.
sys@11GDEMO> select INDEX_NAME, CLUSTERING_FACTOR from user_indexes where INDEX_
NAME = 'LAST_NAME_IDX';
INDEX_NAME CLUSTERING_FACTOR
------------------------------ -----------------
LAST_NAME_IDX 2
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9523925/viewspace-1043939/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9523925/viewspace-1043939/