SQL Server 数据库的整理优化的基本过程(二)

高建刚

第一节 基本维护

第二节 索引

 

索引相信大家都不陌生,而且在因特网上,有了很多关于如何通过索引来优化数据库的文章,在这里,我主要是结合我的使用情况向大家推荐关于索引如何来提高和改善数据库性能的。

众所周知,在数据库的数据存储方面,数据是以分页的形式存储的,在数据量较小的时候,如果我们不建立索引,那么整体的性能可能不会受到多大影响,但是如果数据量较大,达到千万、甚至过亿,如果仍然不采用索引,数据库的检索仍然会去遍历所有的页去找找你想要的那一点点数据,就会感觉到简单的查询效率很低,客户抱怨,前端的程序开发人员也对数据库性能不满意,因此使用索引来提高性能这时候就显得特别重要了。

SQL Server 中索引的存放是以平衡树 Balance-Tree(B-Tree) 结构顺序存放的,在有效的利用索引时,系统会根据建立的索引树,通过二分查找方式查找符合条件的记录,同时建立索引后,索引所占用的硬盘空间也会比每条数据记录的硬盘空间小一些,所以说无论是查找方式和读取硬盘的空间都可以达到提高性能和查询效率的目的。索引的理解,好比一本书的目录,读者可以通过目录去快速找到自己想看的章节,而目录在整本书的占用书本页数少,结构简单,索引也是同样的道理,这样可能理解起来就比较容易接受了。

SQL Server 中,索引的结构包含三方面,根节点分页 (Root Level) ,即索引结构的开始。子叶层 (Leaf Level) ,索引的最下层。非子叶层 (Non-Leaf Level) ,介于子叶层和根节点之间的结构。

SQL Server 的索引分为聚集索引和非聚集索引两类 ( 后续内容会单独介绍全文检索和全文索引 ) 。聚集索引每个表只能存在一个,它的建立标志着数据表本身就是索引的一部分,因为指定了聚集索引后,整个表的数据存储都会按照用户建立的聚集索引来摆放,在 SQL Server2000 以后的版本中,聚集索引已经可以指定由大到小还是由小到大的顺序了 ( 还有分区、在线等其他特性,在此不累述 ) 。索引建立后会生成索引结构,也就是索引的根节点和非子叶层级,从而完成整个聚集索引的整体结构。数据表的数据的存放只能有一种原则,所以每个表的索引也就只能有一个聚集索引了。所以选择一个表的字段作为聚集索引时,要慎重。

那么建立聚集索引有什么样的技巧哪?首先我们强调一点,聚集索引和主键是两码事,不可混为一谈,它们分别是表结构的两个重要的机制,有共同的特性,是数据表的重要部分构成,但是两者在应用上存在着本质的区别,虽然 SQL Server 在你不指定聚集索引时,会默认为主键就是聚集索引,但是仍然要记住聚集索引和主键尽量区分对待,聚集索引的建立主要是从数据的读取效率来考虑的,比如说人员信息表,设计上主键一般是人员编号,但是我们在利用人员信息表的时候,一般都会以姓名来过滤或排序,所以我们一般把聚集索引建立在姓名的字段上。

既然提到了主键,在这里简单描述一下主键 ( 看好了,说的是主键 ) ,主键是数据库设计的主要部分,它是数据正确性和完整性的保证,建立主键时我们应该考虑数据库的第三范式的定义和要求,即所有字段内容都与主键有直接关联,而没有间接关联,同时主键也是用来唯一定义表数据的单一记录,选择主键时,要坚持唯一、最小、不可为 NULL 、易获取、基本不变更等条件。

再谈非聚集索引,非聚集索引从结构上来说,他是完全独立于数据表之外的结构,其子叶层存放数据存在着两种类型:书签和聚集索引的键值,原则是根据表是否存在聚集索引来区别的。如果表没有建立聚集索引那么子叶层存放的字段键值和指向数据表符合键值记录的 Row ID ,也就是说文档编号、分页编号与页内记录编号所组合的值 (slot 编号 ) ,即 Heap 数据表。而直接通过 Row ID 来获取数据,就是书签查找,称为 bookmark lookup 。一般的非聚集索引都是要结合聚集索引的,否则只使用非聚集索引可能还会导致数据检索的缓慢,所以要尽量保证数据表的聚集索引的存在和合理性。非聚集索引在一个表上可以存在 249 个,但是建议每个表的聚集索引不要超过 10 个。

了解了上述内容后,我们在建立索引的时候,就可以从整体上去考虑如何建立聚集索引和非聚集索引了。

首先,索引是用来帮助在大数据量的表中查找少量数据而建立的,所以聚集索引的结构所占空间应远远小于数据库表本身,想想如果一本书 400 页,目录就有 300 页,你会看目录吗?

其次,索引键值的重复性越低越好。好比我们在一本书里面用“的”去找寻,几乎每页都有一大堆,重复性极高,索引会反复在前后页面读取,还不如直接遍历效率高。

总之,建立索引一般要遵循数据类型尽量为整型、数据本身尽量唯一、不可为空值等原则。

最后强调,建立索引后,数据的增删改会造成索引的自动维护,所以建立合理的索引就要求特别高,另外为保证数据的增删改的效率,建议类似实时查询、实时监控之类的在反复读取数据,但查询结果不要求非常准确的时候,可以在 SELECT 的语句上增加脏读的关键字,以便提高总体的数据库效率。

罗嗦了很多,不知道大家是越看越糊涂,请批评指正!下一节,唠叨一下索引的维护,望关注。

 

posted on 2010-08-02 07:31  gaojier  阅读(140)  评论(0编辑  收藏  举报