SQL Server 索引

SQL Server 2008-索引 简介

在SQL Server 20008中提供的索引类型主要有以下几类:

  聚集索引 非聚集索引 唯一索引 包含性索引 索引视图 全文索引 空间索引 筛选索引 XML索引

  在SQL Server 2008中按照存储结构的不同,可以将索引分为聚集索引和非聚集索引两类。 而这两类索引正是以上其他索引的基础

 索引的设计原则

选择性

  选择性表示符合你查询条件的记录占总记录的百分比,也就是

     选择性=符合查询条件的记录数量/总记录数量

  这个值越小越好,越小代表选择越高,越适合采用索引

表中有1000万条数据,且表中无任何索引

 表中有1000万条数据,且为id列添加非聚集索引

 表中有1000万条数据,且为origin列添加非聚集索引

 

表中有1000万条数据,且为id列添加聚集索引

 

表中有1000万条数据,且为origin列添加聚集索引

 

使用窄索引

 检查建立索引字段的数据类型

  新建一个test2表,该表有id和name两个字段,数据类型分别为int和char(4),在SQL Server 2008中两者的大小都是4字节(失败)

聚集索引与非聚集索引

聚集索引

 

  当我们创建主键约束时,如果不存在聚集索引并且该索引没有明确指定为非聚集索引,SQL Server 会自动将其创建为唯一的聚集索引。

1.何时使用聚集索引

  ①检索一定范围内的数据

  ②读取预先排序的数据

 

 

2.何时不使用聚集索引

  ①频繁更新的表

  ②宽的关键字

  ③太多的并行的顺序插入(实验出错)

 非聚集索引

  因为聚集索引的关系,将表分为两种 堆表和聚集表,所以也有了两种非聚集索引 

    1.堆表上的非聚集索引

      工作方式:通过扫描堆上的非聚集索引,找到RID,再通过RID获取数据

     2.聚集表上的非聚集索引

      工作方式:通过扫描聚集表上的非聚集索引,找到聚集键值,再通过聚集键值获取数据

      

 

  注意:如果表没有聚集索引,建立了非聚集索引,那么非聚集索引使用的是行号。如果此时又添加了聚集索引,那么所有的非聚集索引引用的RID都要改为聚集索引建。这对性能的消耗非常大,因此应该先建立聚集索引,再建立非聚集索引

非聚集索引的覆盖、连接、交叉和过滤 

非聚集索引之覆盖

  建立的索引使得T-SQL查询不用到基本表,仅仅通过索引查找就得到了所需数据

  由于SQL Server 数据库对索引键的大小和列数有限制,其中最大为900字节和16列。如果组合列的大小超过900字节或者是列数多余16列,系统就会报错。因此产生了一种特殊的覆盖索引结构-非聚集索引之include

非聚集索引之include

  在10万条数据的表中,添加非聚集索引

  在10万条数据的表中,添加非聚集索引,并且用include包含其他列

非聚集索引的交叉

  如果表中有多个索引,那么就可以使用多个索引来执行一个查询。根据每个索引选择小的数据子集,然后执行两个子集的一个交叉集

                        

非聚集索引的连接

  索引连接是索引交叉的特例,它将覆盖索引技术应用到索引交叉。如果没有单个覆盖查询而存在多个索引一起可以覆盖该查询,SQL Server可以使用索引连接来完全满足查询而不需要转到基本表

索引的维护

  实际上,索引的维护主要包括以下两个方面:页拆分、碎片,虽然两者的表现形式本质上有所区别,但是故障排除工具是一样的。

碎片

   一个表中有大量的碎片并不只有坏处。对于一个插入频繁的表来说,有大量的碎片在数据插入时几乎不用担心页拆分的问题,所以大量的碎片意味着较差的读取性能,但也意味着极好的插入性能

   碎片分两种:外部碎片和内部碎片

   1.外部碎片

     外部碎片指的是页拆分而产生的碎片。如向表中插入一行,而这一行导致现有的页空间无法容纳新插入的行,则导致页拆分

 

   2.内部碎片

    内部碎片时页拆分后,导致索引页的数据并不满,有空行。

 

 

 

 

 

 

 

之后又往表中插入50条数据

   3.碎片的解决办法

   删除索引并重建

   缺点:

     1.在删除其间,索引不可用

     2.卸载并重建索引会造成阻塞,也可能被其他请求所阻塞

     3.当表中既有聚集索引,又有非聚集索引时,删除聚集索引,会导致对应的非聚集索引重建两次

    使用DROP_EXISTING语句重建索引

   这种方式不会造成非聚集索引重建两次,但也会造成阻塞

 

 

  使用ALTER INDEX REBUILD语句重建索引

  使用这个语句同样也是重建索引,但是通过动态重建索引不需要卸载并重建索引,优于前两种方法,但依然会造成阻塞。可以通过online关键字减少锁,但会重建时间加长。

  因为该操作是一个原子操作,如果它在结束前结束,所有到那时为止进行的碎片整理操作都将丢失

  使用ALTER INDEX REORGANIZE 重整索引

  这种方式不会重建索引,也不会生成新的页,仅仅是整理叶级数据,不涉及非叶级,当遇到加锁的页时跳过,所以不会造成阻塞。但同时,整理效果会差于前三种

查询查询语句执行情况

SQL Server 数据库提供了——执行计划

 MySQL 数据库提供了——explain命令

Oracle数据库提供了——可以手动配置的执行计划

 SQL Server 的5种查询记录方式:

  [Table Scan] 表扫描(最慢),对表记录逐行进行检查

  [Clustered Index Scan] 聚集索引扫描(较慢),按聚集索引对记录逐行进行检查

  [Index Scan] 索引扫描(普通),根据索引滤出部分数据再进行逐行检查

  [Index Seek] 索引查找(较快),根据索引定位记录所在位置再取出记录

  [Clustered Index Seek] 聚集索引查找(最快),直接根据聚集索引获取记录

                 

                       

  

  

其中表中无任何索引结构,检索表中数据时,使用的是表扫描

使用表中的聚集索引进行检索数据时,会有两种检索数据方式,分别为聚集索引扫描和聚集索引查找

使用表中的非聚集索引进行检索数据时,会有两种检索数据方式,分别为索引扫描和索引查找

以下情形会使得索引查找变成索引扫描

隐式转换

 

非SARG谓词导致执行计划从索引查找变为索引扫描

  不满足SARG形式的语句最典型的情况就是包括非操作符的语句,如:NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE、谓词使用函数、谓词进行运算,以下对几种情况进行图示说明

  索引字段使用函数会导致索引扫描

  索引字段进行运算会导致索引扫描

  LIKE模糊查询会导致索引扫描

  警告:

    1.当表中只有非聚集索引,没有主键或聚集索引,这时候搜索走表搜索

 

    2.当表中既有主键(默认聚集索引),又有非聚集索引。如果非聚集索引无法单独删除,这时搜索走聚集查找/扫描

 

 

    3.当表中既有主键(聚集索引)和非聚集索引,且非聚集索引可以单独删除。这时搜索走索引查找/扫描

SQL查询返回数据页达到了临界点会导致索引扫描或表扫描 

 

  经过调试发现1万(24条),10万(234条),100万(2137条),1000万(19570条),所以初步统计临界点在0.0024%以下,且随着表中总数据量的增长而降低

 谓词不是联合索引的第一列会导致索引扫描

  如果不是联合索引,只是单独在id列建立非聚集索引

 

posted @ 2018-03-21 16:54  李大發  阅读(241)  评论(0编辑  收藏  举报