本文目的
分享本人阅读《SQL优化最佳实践》的经验,希望对大家有所帮助。
聚簇因子简介
对于一个sql,数据库在制定执行计划的时候,需要参考统计信息,关于统计信息的内容可以查看我的这篇文章五分钟读完《SQL优化最佳实践》之原理篇,SQL优化必看。
在统计信息中,索引的统计信息是尤为重要的,其中聚簇因子更是数据库制定执行计划中是否采用索引扫描的重要参考依据。
那么聚簇因子到底是啥呢,它是用来标识表中的数据的存储顺序和某些索引字段顺序的符合程度。这句话有点抽象,下面具体讲解一下。
表中的数据是存储在不同的块中的,通过扫描这些块,我们来获取表中的数据。大多数的场景下,我们只需要获取表中符合某些条件的数据,如果我们每次都要扫描全部的块(全表扫描)来获取数据的话,在数据量很大的时候,这显然是无法接受的。那么我们能不能通过sql中的条件来提前得知我们的数据存储在哪些块中呢?当然可以,这也就是索引的工作。
假设我们有一张表A,c为表A的一列,我们在c列建立索引i。表A中块情况如下:
索引i的存储情况如下,图中对相关信息进行了省略。
上图中,我们看到索引的叶子节点中存储有两个信息,一个是索引的健值,对应为c列中的值,另外一个就是rowID,通过rowID我们很容易就可以找到数据所在的块。所以,我们可以得到索引对应的块情况,如下图所示。
聚簇因子计算
好了,我们现在就可以来计算聚簇因子了。算法描述如下:
- 初始化聚簇因子clustering_factor为1。
- 遍历索引叶子节点,如果相邻叶子节点的数据在同一个块中,clustering_factor = clustering_factor + 0,否则clustering_factor = clustering_factor + 1。
我们来计算上图中的聚簇因子。I1中的数据在K1块,I2中的数据也在K1块,聚簇因子+0保持不变,I3的数据在K3块,同I2不在一个块中,聚簇因子+1,以此类推,即可。
聚簇因子最小是表存储的块数,最大是表中的记录数。当聚簇因子接近表的存储的块数的时候,表明索引字段的存储顺序跟表中存储的顺序符合度较高,索引扫描效率很高;相反,当聚簇因子接近于表中的数据量的时候,全表扫描的效率有时会更高!
查看
下面的代码展示了如何来查看表的块数,以及索引的聚簇因子等信息。
[hf@testdb] SQL> create table t1 as select rownum id, object_name name from dba_objects whererownum<=50000; Table created. [hf@testdb] SQL> create index idx_t1 on t1(id); Index created. [hf@testdb] SQL> exec dbms_stats.gather_table_stats(user,'t1',cascade => true); PL/SQL procedure successfully completed. [hf@testdb] SQL> select blocks,num_rows from user_tables where table_name = 'T1'; BLOCKS NUM_ROWS ---------- ---------- 252 50000 [hf@testdb] SQL> select index_name, blevel, leaf_blocks, clustering_factor fromuser_indexes where table_name = 'T1'; INDEX_NAME BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR ------------------------------ ---------- ----------- ----------------- IDX_T1 1 110 240
注意:上面代码块中表的块数为252,但是实际存储数据的块只有240个。
关注大白,带你阅读技术书籍,了解技术内幕!