索引杂记

一、概念

查询执行的大部分开销是I/O,使用索引提高性能的一个主要目标是避免 全表扫描,因为全表扫描需要从磁盘上读取表的每一个数据页,如果有索引指向数据值,则查询只需要读少数次的磁盘就行啦。所以合理的使用索引能加速数据的查询。但是索引并不总是提高系统的性能,带索引的表需要在数据库中占用更多的存储空间,同样用来增删数据的命令运行时间以及维护索引所需的处理时间会更长。所以我们要合理使用索引,及时更新去除次优索引。

二、SQL Server 使用4种类型的数据页面来管理表或索引:

  • IAM页

    操作系统之所以能管理Disk,是因为在系统启动时首先加载了文件分配表:FAT(File Allocation Table),正是由它管理文件系统并记录对文件的一切操作,系统才得以正常运行;同理,作为管理系统级的SQL SERVER,也有这样一张类似FAT的表存在,它就是索引分布映像页:IAM(Index Allocation Map)。

  • 数据页

    保存非文本/图像类型的数据,因为它们都不超过8K的容量

  • 文本/图像页

    只保存超过8K容量的文本或图像类型数据

  • 索引页

    保存的是与索引结构相关的数据信息

三、索引分类

  • 聚集索引

    聚集索引把数据按照物理顺序进行排列,所以不可能有多种排法,所以一个表只能建立一个聚集索引,但是可以是一个字段也可以是多个字段结合。
    由于在聚集索引下,数据在物理上是按序排列在数据页上的,重复值也排在一起,因而包含范围检查(between,<,><=,>=)或使用group by 或order by的查询时,一旦找到第一个键值的行,后面都将是连在一起,不必再进一步的搜索,避免大范围的扫描,可以大大提高查询速度。

  • 非聚集索引

    sqlserver默认情况下建立的索引是非聚集索引,它不重新组织表中的数据,而是对每一行存储索引列值并用一个指针指向数据所在的页面。他像汉语字典中的根据‘偏旁部首’查找要找的字,即便对数据不排序,然而他拥有的目录更像是目录,对查取数据的效率也是具有的提升空间,而不需要全表扫描。
    一个表可以拥有多个非聚集索引,每个非聚集索引根据索引列的不同提供不同的排序顺序。

四、索引的设计原则

对于一张表来说,索引的有无和应该建立什么样的索引,需要取决于where子句和join表达式。

  • 系统一般会给主键字段自动建立聚集索引,所以主键字段一般使用int类型为好,如果使用guid类型,聚集索引是无效的,这时候可以使用时间字段作为聚集索引。
  • 有大量重复值且经常有范围查询和排序、分组的列,或者经常频繁访问的列,考虑建立聚集索引。
  • 在一个经常做插入操作的表中建立索引,应使用fillfactor(填充因子)来减少页分裂,同时提高并发度降低死锁的发生。如果该表为只读表,填充因子可设为100.
  • 在选择索引键时,尽可能采用小数据类型的列作为键以使每个索引页能容纳尽可能多的索引键和指针,通过这种方式,可使一个查询必需遍历的索引页面降低到最小,此外,尽可能的使用整数做为键值,因为整数的访问速度最快。
  • 非聚集索引组合键的索引建立需要根据where查询条件来决定,比如组合键为 a,b,c,那么where条件就得是a= b= c=三个条件一起,只有一个或两个条件索引是不会匹配的。

页分裂
一半的数据将保留在老页面,而另一半将放入新页面,并且新页面可能被分配到任何可用的页。所以,频繁页分裂,后果很严重,将使物理表产生大量数据碎片,导致直接造成I/O效率的急剧下降,最后,停止SqlServer的运行并重建索引将是我们的唯一选择!
填充因子
索引的一个特性,定义该索引每页上的可用空间量。FILLFACTOR(填充因子)适应以后表数据的扩展并减小了页拆分的可能性。填充因子是从0到100的百分比数值,设为100时表示将数据页填满。只有当不会对数据进行更改时(例如 只读表中)才用此设置。值越小则数据页上的空闲空间越大,这样可以减少在索引增长过程中进行页分裂的需要,但这一操作需要占用更多的硬盘空间。填充因子指定不当,会降低数据库的读取性能,其降低量与填充因子设置值成反比。

你可能感兴趣的:(数据库)