集群因子用于判断索引回表需要消耗的物理I/O次数。
这里在测试表test上创建一个索引:
create index idx_id on test(object_id); select owner, index_name, clustering_factor from dba_indexes where owner = 'TEST' and index_name = 'IDX_ID';
结果展示:
OWNER INDEX_NAME CLUSTERING_FACTOR -------------------- -------------------- ----------------- TEST IDX_ID 1597
索引idx_id的叶子块中有序地存储了索引的键值以及键值对应所在的Rowid.
SQL> select * from (select object_id, rowid from test where object_id is not null order by object_id) where rownum<=5; OBJECT_ID ROWID ---------- ------------------ 2 AAASACAAFAAAA0TAAi 3 AAASACAAFAAAA0TAAJ 4 AAASACAAFAAAA0TAAh 5 AAASACAAFAAAA0TAAk 6 AAASACAAFAAAA0TAAK
首先我们比较 2、3 对应的 ROWID 是否在同一个数据块,如果在同一个数据块,Clustering Factor +0;如果不在同一个数据块,那么 Clustering Factor 值加 1。 然后我们比较 3、4 对应的 ROWID 是否在同一个数据块,如果在同一个数据块,Clustering Factor 值不变;如果不在同一个数据块,那么 Clustering Factor 值加 1。 接下来我们比较4、5对应的ROWID是否在同一个数据块,如果在同一个数据块,Clustering Factor +0;如果不在同一个数据块,那么 Clustering Factor 值加 1。 像上面步骤一样,一直这样有序地比较下去,直到比较完索引中最后一个键值。
根据算法我们知道集群因子介于表的块数和表行数之间。 如果集群因子与块数接近,说明表的数据基本上是有序的,而且其顺序基本与索引顺序一 样。这样在进行索引范围或者索引全扫描的时候,回表只需要读取少量的数据块就能完成。 如果集群因子与表记录数接近,说明表的数据和索引顺序差异很大,在进行索引范围扫描 或者索引全扫描的时候,回表会读取更多的数据块。 集群因子只会影响索引范围扫描(INDEX RANGE SCAN)以及索引全扫描(INDEX FULL SCAN),因为只有这两种索引扫描方式会有大量数据回表。 集群因子不会影响索引唯一扫描(INDEX UNIQUE SCAN),因为索引唯一扫描只返回一 条数据。集群因子更不会影响索引快速全扫描(INDEX FAST FULL SCAN),因为索引快速全扫描不回表。
查看一下表的总块数
SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)) blocks from test.test; BLOCKS ---------- 1411
再次强调一遍,在进行 SQL 优化的时候,往往会建立合适的组合索引消除回表,或者建 立组合索引尽量减少回表次数。如果无法避免回表,怎么做才能消除回表对 SQL 查询性能产生影响呢?当我们把表中所 有的数据块缓存在 buffer cache 中,这个时候不管集群因子多大,对 SQL 查询性能也没有多大 影响,因为这时不需要物理 I/O,数据块全在内存中访问速度是非常快的。
标签:Clustering,20,扫描,回表,索引,集群,Factor From: https://www.cnblogs.com/zmc60/p/17660795.html