sql优化的两个参数

今天群里一个兄弟说,有个SQL按某个索引执行时就很快,按时间走就很慢,让查了下表的数据量和distinct_keys,以及clustering_factor,一个num_rows是9000多W distinct 900多,一个是num_rows也是9000多W,distinct 20000多。但是

clustering_factor 两者相差10000多,这也是为什么前者比后者快的原因。按理说distinct 大的索引的选择性比较高。但是这里却因为clustering_factor导致后者慢

顺便也了解下这几个参数和索引的关系

clustering_factor 是表征表中数据的存储顺序和某索引字段顺序的符合程度。

oracle 按照索引块中存储的rowid 来识别相临的索引中记录 在 表block中是否为相同块,如果索引中存在记录 rowid a,b,c,d……,若b 和 a 是同一个block,则比较 c 和 b,若这时不是同一个block,则clustering_factor + 1 ,然后比较 d 和 c,若还不是同一个 block,则clustering_factor + 1 ……

这样计算下来,clustering_factor 应该是介于 表 block数量 和 表记录数之间 的一个值,若 clustering_factor 接近 表block数量,则说明表中数据具有比较好的跟索引字段一样排序顺序的存储,通过索引进行 range scan 的代价比较小(需要读取的表块可能比较少),若clustering_factor 接近 row数量,则说明表中数据和索引字段排序顺序差异很大,杂乱无张。则通过索引进行 range scan 的代价比较大(需要读取的表块可能更多)。

当然,在oracle 920 开始,对于cluster_factor 比较接近表块数量的根据索引的大范围查询做了特别的处理,不再是读一个索引记录去搜索一个表记录了,而是成批处理(通过索引块一批rowid一次去表块中获得一批记录),这样就大大节约了读的成本( consistent gets)。

选择性可以通过公式度量:(从查询中返回的行/表中所有的行).表中仅有一行可以满足查询的独特索引具有100%的选择性,并且这种索引总会被使用.如果返回行的百分比较抵,这个索引就有高度的选择性,它容易被查询优化器选择.如果百分比高在表中许多行都会被获取,则选择性抵,索引的用处不大.正如以上提到的,索引选择性至少需要90%如果表需要返回超过10%的行,则索引的选择性就太低了,这个索引就会被忽略.事实少年宫,经常的情况是,如果查询要获取的行超过5%,查询优化器就会选择不同的索引或者执行表扫描.事实上,在查询优化器选择一个索引之前,它希望可以90%-95%的行.一个比较好的消息就是你可以很容易地度量选择性.如果选择性超过95%,则这个索引就很有可能被选择以满足查询.

密度

密度定义了行中重复值的百分比.密度的范围从0-1.低密度值更受欢迎,高选择性的索引有低的密度值,通常范围从0.05-0.10.如果换算成选择性95%-90%.如果索引上的密度值超过了0.10,它就可能不被使用.当使用非群集索引的时候,数据怎样访问.数据页会按照索引的次序获取,除了在页需要被再次访问的很少情况下,请求不会是顺序的.

在建立有用的索引的时候,列的唯一性是一个重要的变量.唯一性高对于非群集索引来讲是一个很好的选择.与此相对的,唯一性低对于群集索引来讲是一个很好的备选,唯一性非常小(小于3)的列根本不能被索引.

        选择性可以通过分析索引的分布统计得到.通过使用DBCC SHOWCONTIC 或者DBCC SHOW_STATISTICS 可以检查索引列上的数据分布.它们可以为索引的选择性和密度提供一个很好的度量.DBCC SHOWCONTIC 对于理解一个表或者索引的碎片程度有用.DBCC SHOW_STATISTICS 可以显示索引中包含有多少个重复值.重复值的数量越高,选择性就越低,要记住,在索引选择期间,查询优化器更偏好高选择性.



评论暂缺

(Required)
(Required, will not be published)