作为数据库管理员来说,要在表上建立索引很简单。但是要知道这个索引是否合适、如何优化索引则就具有一定的难度。这项工作也是用来评价一个数据库管理员是否算得上专家的一个重要指标。那么为什么索引优化有这么大的难度呢?这主要是因为索引优化是考察一个数据库管理员经验的时候。笔者今天就跟大家分享一下这方面的管理经验。
其实在数据库中本身就提供了一些比较有参考价值的信息,可以帮助管理员来做好索引的设计与优化。二元高度就是Oracle数据库中帮助数据库管理员来做好这个工作的工具。什么叫做二元高度呢?说实话笔者也不了解这个名词具体代表的含义。只知道索引二元高高度对把Rowid返回给用户进程时所要求的I/0数量起到非常关键的作用。数据库管理员只要了解这个即可,而不需要花费很长的时间去搞明白什么叫做二元高度。在Oracle数据库中,系统视图sys.dba_indexes就保存在索引的二元高度信息。如下图所示的SQL语句,可以查询处索引的二元高度的值。
如上图所示,字段Blevel表示二元高度;Index_name则表示索引的名称。一般来说,二元高度越低越好(最低为0)。作为数据库管理员,就是需要相方设法让这个二元高度的值变为0。虽然这个目标看起来比较简单,但是实现起来却有相当大的困难。
一、二元高度对索引的影响。
为了说明二元高度对索引的影响,笔者举一个例子为大家说明。假设现在有一个索引,其二元高度为3。此时如果用户需要利用这个索引来查询数据的话,则此时同时将会有4个块被读取,其中3个来自索引,一个来自表。随着索引二元高度的值的增加,整个检索数据所要求的I/O数量也会随之增加。因为二元高度增加一个级别都会增加一个额外的读取快。而且通常情况下由于这些块布能够按照顺序读取,他们都会要求一个独立的I/O操作。所以在这个二元高度的值越大,其I/O争用的现象也可能会越频繁。此时其数据库索引的性能也就会越低。
二、如何来查找二元高度的值?
通常情况下,数据库管理员可以对索引或者表进行分析从而得到索引的二元高度。不过这个分析比较复杂。笔者是建议各位数据库管理员直接查询数据视图sys.dba_indexes,来获得系统当前索引的二元高度值。既然数据库中已经有类似的值,那么就没有必要浪费时间在去手工分析这些值了。以前笔者在给跟一些数据库管理员沟通的时候,他们也询问过笔者,这个二元高度的值是如何计算出来的。笔者给他们解释了好半天,他们仍然搞不明白。其实这也怪不得他们,因为笔者对这个计算分析的过程也是一知半解。所以不知道这个二元高度的值怎么计算出来的,没有关系。只要知道该从哪个地方去查找这个值即可。
三、哪些因素会影响到这个值?
在对索引进行优化的时候,就是要想尽一切办法,把这个值降低到最低。而要实现降低这个二元高度的值的目标,则数据库管理员就必须先了解哪些因素跟这个值有关。如此的话,数据库管理员才能够对症下药,降低二元高度的值,提高索引的性能。
1、删除操作。有时候数据库管理员可能会发现他们刚完成数据的导入工作,就会发现数据库的性能有所下降。而此时查询这个二元高度的值,则会发现这个值非常的大。照理来说,才刚完成数据的导入功能,还没有进行其它的一些业务操作,这个值不应该很大呀。那这是怎么一回事情呢?其实,这主要是因为大量的删除操作所造成的。原来在导入数据的时候,可能会发现某些数据导入有问题。故有些数据库管理员会利用delete语句清除倒入到数据库中的记录。此时数据库管理员就需要注意,索引上如果有大量被删除的行,则它对应的二元高度的值也就会逐渐增加。遇到这种情况时,数据库管理员可以尝试着重建索引。通常情况下,如果二元高度的值比较大确实是因为删除操作所引起的,那么通过这个重建索引的工作后,基本上可以把这个二元高度的值降下去。笔者建议,如果一个索引中被删除掉记录接近于全部记录的30%左右,此时数据库管理员就需要采取重建索引的作业,用于降低二元高度以及在一次I/O过程中所读取的空闲时间。
2、数据块尺寸。通常情况下,数据库块尺寸与二元高度的值是成反比的。数据块尺寸越大,则索引的二元高度就越低。数据块大小是表空间管理中的一个属性。通常情况下,数据库管理员在创建表空间的时候,往往采用其默认的块大小,而不会改变其大小。System与Sysaux是系统表空间,他们的数据块大小往往是在表空间创建时的初始化参数定义的。一般情况下不同的表空间可以由不同的块大小,以对应不同的表空间对于性能的不同要求。不过总的来说,这个数据库块也不是说分的越细越好。这会增加数据库维护的难度。在Oracle数据库中,对此也做了一定的限制。如正常情况下,这个数据库最多可以设置五个不同的数据块大小。`数据库`是以数据块为单位分配和使用磁盘空间,一个数据块是磁盘空间中固定个数的字节,位于磁盘空间管理的最底层。通常情况下,一个数据块的大小从8KB到32KB之间。并不是说,其可以取到8KB到32KB之间的任何值,其还必须满足必须是存储器设备的物理块大小的一个倍数。如数据库存储器设备的存储快大小为8KB的话,则这个数据块的大小就可以为8、16、24、32KB中的任何一个值。如果不考虑其他因素,在创建数据表时设置比较大的数据块,可以降低二元高度的值,可以产生比较浅的B树,可以产生比较佳的性能。一般来说,如果数据库管理员认为数据库比较复杂,所涉及的应用比较大的话,在可以把数据块设置的比较大一点,如24KB,甚至32KB。这里需要注意的是,如果数据库系统用来做数据仓库,则最好把这个数块设置为32KB。而对于其他用途的数据库,则需要根据数据库应用的负责程度来进行合适的设置。如果要说把数据库块大小设置为多少合适,要定一个具体的值,恐怕没有人可以轻易下这个结论。数据库管理员需要根据企业数据库的实际应用,来确定一个合适的值。而这就跟数据库管理员的经验挂钩了。丰富的数据库管理经验,可以帮助管理员来设置一个合适的数据块。如果只数据库只用来学习用的话,那么在创建表空间时可以忽略这个参数,直接采用默认的数据块大小即可。而如果数据库用来当作生产用数据库时,则对此数据库管理员就需要慎重考虑。可以结合这个索引相关的二元高度参数来判断当前的数据库块大小是否合适。
3、二元高度的值还会随着索引列中的非NULL数量以及索引列中值的范围狭窄程度而变化。一般来说,索引列中非NULL的数量越多(即空字段余越少)则其二元高度的值越低。或者说,索引列中的值越靠近,即范围比较小,则其二元高度的值也就越低。为此,这就提醒数据库管理员在设计索引的时候,最好能够把索引字段设置为非空。如此的话,就可以降低索引的二元高度,以提高索引的性能。如笔者在索引设计时,往往把索引字段设置为非空。而用户在实际应用的过程中,如果这个索引字段暂时不需要输入内容(如可能暂时无法取得这个值,需要在后续补入),此时系统就会采用一个默认值(如NULL),来表示这个字段的内容暂时为空。不过在数据库存储的时候,已经有具体的内容了。如此即可以满足索引列非空的需要,用户在日后也可以修改这个信息;同时又降低了二元高度的值,提高了数据库索引的性能。一举多得,数据库管理员可以尝试。另外,把索引列的值在满足应用的前提下,限制在一个比较小的范围之内,也可以降低这个二元高度的值。