[DB2]数据库设计:取得最佳性能的准则 (8)

发表于:2007-05-26来源:作者:点击数: 标签:
五、索引设计方面的考虑 索引也是一种DB2对象(一个单独的VSAM数据集),它由一组排好序的键组成,这些键是从相应表中的一个列或多个列抽取出来的。很多DB2专家声称,只有为表空间建立恰当的索引,才是使得访问该表空间中DB2数据的应用程序的 性能 达到最佳
五、索引设计方面的考虑

 

 

  索引也是一种DB2对象(一个单独的VSAM数据集),它由一组排好序的键组成,这些键是从相应表中的一个列或多个列抽取出来的。很多DB2专家声称,只有为表空间建立恰当的索引,才是使得访问该表空间中DB2数据的应用程序的性能达到最佳、最有效的效果。数年前,在I/T中DASD的成本和空间是更重要的考虑因素。随着技术的发展,通过增加更多的索引(或添加列到已有的索引中)来减少I/O,以及由此消耗的额外磁盘空间,这几年两者之间的权衡已经变得越来越有吸引力。索引所带来的主要性能好处是:

 

 

  1) 提供指向表中被请求的数据行的直接指针。

 

 

  2) 如果结果集要求的顺序与索引一致,则可以消除排序。

 

 

  3) 如果被请求的列都包含在索引项中,则可以避免不得不读数据行的情况。

 

 

  1. 分区索引

 

 

  在DB2 UDB V7中创建分区的表空间时,DB2根据CREATE INDEX语句的PART子句将数据划分到几个分区上。那样的索引就成为所谓的分区索引,而这种分区的方法就被称为 索引控制的分区(index-controlled partitioning)。对于分区索引,建议选择不大可能改变的键列。如果对那些列进行更新,则可能导致一行从一个分区转移到另一个分区,从而降低了性能。

 

 

  DB2 V8一个重要的特性是表控制的分区(table-controlled partitioning)。这时,当创建分区的表时,分区的边界由CREATE TABLE语句决定,而不是由CREATE INDEX语句决定。对于索引控制的分区方法,分区的表、分区索引和群集这几个概念之间有点纠缠不清。而在表控制的分区方法中,这三个概念是各自独立的。这种增加的灵活性使您可以考虑更多潜在的设计方案,因而也增加了提高DB2数据库及其应用程序性能的机会。

 

 

  2. 何时建立索引

 

 

  CREATE INDEX语句使用户可以立即建立索引,或者将索引的建立推迟到方便的时候。如果立即建立索引,则需要扫描表空间,这样要花费比较多的时间。通过指定DEFER,则可以推迟索引的创建。

 

 

  只要有可能,应该在初次装载一个表之前创建其所有索引,因为LOAD实用程序建立索引的效率比CREATE INDEX过程要高。如果需要在一个已有的(并且被填充的)表上创建一个索引,那么可以使用DEFER子句。然后可以在晚些时候使用REBUILD INDEX实用程序,这个实用程序与LOAD实用程序一样,是更为有效的填充索引的方式。

 

 

  3. PIECESIZE

 

 

  DB2 UDB V5中引入了一个新特性,这种特性使您可以将一个非分区索引(non-partitioning index,NPI)拆成数块,然后控制将组成索引空间的多个数据集的大小。通过使用这些小块,可以使NPI的索引页散步到多个数据集中。

 

 

  通过在CREATE或ALTER INDEX语句中指定关键字PIECESIZE,可以确定各块的大小。PIECESIZE的值必须是2的幂,其大小可以介于256KB到64GB之间。对于常规表空间,PIECESIZE的默认值是2GB,对于LARGE表空间,默认值是4GB。如果NPI极有可能显著增长,那么应选择一个更大的值。在为主空间和辅助空间(CREATE INDEX语句的PRIQTY和SECQTY选项)的分配确定值时,也应该留意PIECESIZE的值。

 

 

  通过使用这个选项,可以促进并行性,从而提高NPI的扫描性能。另一个好处是可以减少在读或更新的处理过程中对I/O的争用。通过指定一个较小的PIECESIZE,可以创建更多的块,从而对块的放置有更多的控制。将这些块放在不同的I/O路径中,可以减少访问NPI所需的SQL操作的争用。

 

 

  4. 理想的索引

 

 

  通过检查应用程序中的SQL语句,可以建立一种想象起来很好的索引。

 

 

  1) 首先,在索引中包括WHERE子句中的所有列,这样,就可以使用索引形成的屏蔽来拒绝结果集中不合格的行。将这些列放在索引的开始部分。这样一来,当对SQL语句进行EXPLAIN时,就可以产生最大的MATCHCOLS值。

 

 

  2) 接下来,确保索引中这些列有适当的顺序(按照ORDER BY子句),这样可以避免排序。在进行EXPLAIN时,通过检查PLAN_TABLE中所有不同的SORT*列,便可以确认这一点。

 

 

  3) 最后,如果可能的话,将SELECT中所有的列包括到索引当中,这样就不需要访问表中的行。这样的索引项可以提供所有被请求的数据。这在EXPLAIN中就表现为INDEXONLY = Y。   
  在很多情况下,实现这一理想的代价太高,也不切实际,甚至是不可能的。对于一个索引中可以包括的列数,以及整个索引项的长度,都有架构上的限制(虽然这些限制已考虑到相当大的索引项长度和灵活性)。而且,也要考虑索引维护的成本。虽然建立理想化的索引可以显著提高查询性能,但是每当对DB2数据库执行SQL写操作(INSERT、UPDATE 或 DELETE)时,上述理想化的索引都会有负面的影响。因此,您常常可以选择实现只包括在WHERE和ORDER BY子句中引用到的列的索引。

原文转自:http://www.ltesting.net