ITPub博客

首页 > Linux操作系统 > Linux操作系统 > oracle的索引原理与调整

oracle的索引原理与调整

原创 Linux操作系统 作者:无名雪狼 时间:2011-04-02 12:22:54 0 删除 编辑
    在刚开始接触数据库、刚开始接触索引是,我总是觉得索引这是一个好东西,因为在我的印象里它总是明确的告诉每一个数据库操作精确的匹配,而且速度很快,但让我伤心的却是:索引并非总是如此,甚至有时候给人带来很大的麻烦。

       oracle中,数据的选择性和数据在表块上的分布情况是索引改进性能的重要因素。一般对于选择度高、数据有序分布的列,在其上创建索引可以很好的提高性能(当然是在需要的情况下),因为选择度高的列可返回给oracle较少的ROWID,得到更加精确的ROWID能减少磁盘的I/O。对于表的记录有序分布的情况下,也可以减少磁盘的I/O,因为对于给定范围的where条件的值,当索引返回ROWID时,所需记录在相同数据块的概率会更大,对于无序存储表中的行时,可能要读取三块表块的操作,如果表的记录是有序存储的就很有可能只要读取一个数据块。

       对索引的扫描如果不是快速全局扫描,那么在扫描所以时不会一次返回多个块,因为索引中返回的块并不是连续的,并且对于B树索引的树枝块并没有存储相邻树枝块的指针,所以无法进行多块一起返回。但是对于快速全局扫描,却可以再一次I/O中返回多个块,从而加快了I/O操作并提高性能,因为在每个leaf block中都指向前、后块的指针,但是这需要设置初始化参数db_file_multiblock_read_count参数,否则将不能在一次I/O中同时返回多个块。但我仅仅了解到这里的时候,我甚至在心里暗自下定决心,以后就将这个参数设置为true了,因为这可以加快I/O操作。但是后来我才发现,我太幼稚了,因为设置了db_file_multiblock_read_count参数后,oracle的优化器可能会执行跟多的全表扫描,对于某些操作我却并不希望执行全表扫描,因为对于某些操作全表扫描的速度将会比使用索引更慢,这时就需要设置初始化参数optimizer_index_cost_adj来驱动oracle对索引的使用。

      

       对于索引的性能调整,首先要做的就是调整那些糟糕的SQL语句,因为在很多时候,查询性能的降低可能只是因为糟糕的SQL语句。那些语句可能限制了索引的使用,或者使用了不正确的表的连接顺序(为什么优化器不能总是调整好表的连接顺序呢?我不解!)。对于SQL语句,不应该使用不等于运算符、IS NULLIS NOT NULL、使用函数、比较不匹配的数据类型,因为这些都会限制索引的使用从而降低查询速度。

       当然,在创建索引是,就应该选择那些选择性高的列创建索引,因为这可以提高索引的性能。如果对于一个表中某个列的数据发生了严重的数据偏斜,那么可以在该列上创建直方图来告诉优化器该使用哪个索引能是性能更优。与此同时,也因该关注索引的binary heightclustering factor,因为如果clustering factor比较低的话,说明表是有序存储的,同时需要读取的表块数量将会减少很多。对于binary height,也就是一个索引的二叉树的深度,例如深度为3的索引,则可以说其为3级,其中根为第一级,leaf block为第三极,所以的级越低,在执行查询的所要执行的I/O就越少,增大块的尺寸可以降低所以的级数。当索引上有大量的删除的行时,索引的binary height也会增加,重建索引或许会降低索引的binary height,但是这并不能带来多大的性能改观。

       其实,对索引的匹配扫描读取并不见的就是最快的,有时候对索引全局扫描可能还要更快。如果一个索引的大小对于表来说很小的话,那么执行快速全局扫描(使用index_ffs提示)可以是查询的速度提高很多,但是如果索引的大小不比表小多少或比表还要大,那么执行快速全局扫描反而会降低速度。

 

T.jpg

12.jpg

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25244847/viewspace-691551/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2011-01-14

  • 博文量
    9
  • 访问量
    32069