停止空想

老张的空中之家

Block Selectivity and Row Selectivity

作者:admin 发表时间:六月 - 5 - 2006

部分来自 Cary Millsap

 

Row selectivity 就是说select的行占该表中所有行的百分比

Block selectivity 就是说select的行所拥有的块占整个表块的百分比

 

我写过篇文章——Select多少百分比的数据才可以使用index?(blog上面有) 这个百分比指的是row selectivity。但是block selectivity也非常的重要。因为如果row selectivity非常小,比如100万行的表,select * from tab where x=’a’ ,只有1万行, 但是该表每个块上面都有这个行,也就是说block selectivity非常大 ,这样在select的时候就需要将全部的块都select一遍,但是根据row selectivity,就肯定使用index,

这样反而严重的影响了效率。 其实也就是说数据的物理分布相当的重要,这是我们在建立索引的时候不得不考虑的问题。


 

另外还有一点原来的那篇文章也没有提到,那就是数据的逻辑分布比如上面的例子,该表有100万行的数据,x列上面有10个distinct值,比如1~10,2~10都是较少的出现,但是x=1出现了90多万行,也就是说这个表在这一列上严重的skew了。一般的对该表进行分析或者使用对该表空间进行分析的命令:

exec dbms_stats.gather_table_stats (‘user’,’tab’) ;

这时并没有对indexed columns进行数据逻辑分布的柱状图分析,可以通过user_tab_col_statistics的num_buckes列来验证,这时该列为1,也就是说没有柱状图。这个时候在select * from x=1的时候,还是使用了该列上的index,效率低下。但是

exec dbms_stats.gather_table_stats (‘user’,’tab’, method_opt=>’for indexed columns size 75); 这样显性的收集柱状图信息的命令就可以达到让上面的select 选择全表扫描这一执行计划的目的。

 

应该说数据的逻辑分布还是可以归到row selectivity 的范畴里面。如果x=1的行多了,全表扫描,如果少了则使用index,但是row selectivity毕竟解决不了下面这样的问题。

 

  EC_PO_ID   Block            Block count (b)    Row              Row count (r)  

                  selectivity(pb = b/B)              selectivity(pr = r/R

 8               63.50%           1,051                0.54%            1,606  

 

也就是上面说的数据物理分布可能遇到的问题。

这种情况下,如果在ec_po_id 上面的列作了index,因为该列中的row selectivity都非常的高,所以即使做了柱状图,oracle肯定也会选择使用index;但是block selectivity非常的差,这个时候全表扫描的效率反而比使用index高的多。一般如果ec_po_id列中,这样的值很多,比例很大的话,不建议在该列上建立index。

 

所以block selectivity有时候可以用来作为判断是否应该建立index的标志

1. Every value’s block selectivity is so good that you definitely do want to create an index for the column.

2. Every value’s block selectivity is so poor that you definitely do not want to create an index for the column.

3. Block selectivity is poor for some values, but good for others. 这种情况最多见,应该判断是否值得建立索引。

 

比如下面的这种情况:

 

id value      Row selectivity (pr)     Block selectivity (pb)

                   

01                    89.87%                    100%

02                     2.34%                      7%

03                     2.16%                      6%

04                     1.86%                      2%

05                     1.42%                      1%

06                     1.17%                      1%

07                     0.75%                      1%

08                     0.18%                      < 1%

09                     0.14%                      < 1%

10                     0.11%                      < 1%

TOTAL               100.00%                   N/A

 

但是需要注意的是,一般情形下的row selectivity 与block selectivity 这两个是基本接近的,增长和减少的趋势是相同的。这个时候建立index不成问题,因为可以通过histogram来解决问题。

 

因此在一个列上建立index之前,是需要认真考虑的事情,如果建立了一个好的index,以后的调优工作可以轻松很多。

类别:Oracle

发表评论