以下的文章主要向大家讲述的是SQL Server索引覆盖(Index Covering),SQL Server数据库索引覆盖主要是这种情况,查询中的select 与where子句中所需要的信息都能在非聚集索引中找到。
因为非聚集索引包含了一个对应于表中每个数据行的一个叶子行,SQL Server能从非聚集索引的叶子行来满足查询。这导致了数据检索的更快,因为所有的信息能从索引页中直接获得,并且避免了SQL Server查找数据页。
因为非聚集索引的叶子页都连接在一起,索引的叶级可以像表中的数据页一样进行扫描,因为页级行都典型比数据行要小,一个覆盖了查询的非聚集索引将比同样列的聚集索引更快,因为需要读取的页数要更少。
在下面的例子中,quthors表中的关于au_lname 和au_fname的非聚集索引将覆盖查询,因为结果中的列和SARG都能从索引中提取出来:
- Sql代码
- Select au_lname, au_fname
- From authors
- Where au_lname like "M%"
- GO
- Select au_lname, au_fname
- From authors
- Where au_lname like "M%"
- GO
其他使用聚合函数(MIN AVG SUM COUNT)的查询或者仅仅检查是否存在的查询也能从SQL Server索引覆盖中获益。下面是一些能够利用索引覆盖优点的查询:
- Sql代码
- Select count (au_lname) from authors where au_lname like 'm%'
- Select count (*) from authors where au_lname like 'm%'
- Select count (*) from authors
- Select count (au_lname) from authors where au_lname like 'm%'
- Select count (*) from authors where au_lname like 'm%'
- Select count (*) from authors
你可能会奇怪最后一个查询,它甚至没有一个具体的SARG,怎么还能使用索引。SQL Server知道非聚集索引的特性,一个非聚集索引为表中的每行数据都包含了一行;它能够简单的计算任何一个非聚集索引的行数,而不需要扫描整个表。对最后一个查询,SQL Server选择最小的非聚集索引——也就是,具有最少的叶子页的索引。
向非聚集索引添加列使得发生SQL Server索引覆盖是一种提高查询响应时间的常见方法。考虑下面的查询:
- Sql代码
- Select royalty from titles
- Where price between $10 and $ 20
- Select royalty from titles
- Where price between $10 and $ 20
如果你仅在price列上创建索引,SQL Server能发现满足price在该范围的索引中的行,但是它还需要访问数据行来检索royalty。范围中有100行,最坏情况下检索数据所花费的IO代价计算如下:
引用
索引的级数
+查找匹配行的索引页的数
+100 * 每个书签查找页数
如果royalty列添加到了price列索引中了,索引能被扫描来检索结果,而不是进行书签查找,这样具有更快的查询响应。使用SQL Server索引覆盖的IO代价将只是:
引用
索引级数
+查找匹配行的索引页的数
引用
注意:
当考虑添加索引来利用索引覆盖时,小心使得索引变得太宽。当索引行的宽度接近与数据行宽度时,覆盖的优点将失去,因为增加了叶级页的数目。当索引的叶级页的数目接近了表中页的数目,索引级数也增加了,那么索引扫描的时间就开始接近于表扫描时间了。
另外,如果你添加对到索引中的列频繁修改,数据行中列的任何修改也会波及到索引中。这增加了维护的负担,也会影响修改的性能。
正如第33章讨论的那样,当在一个表上创建了 一个聚集索引,聚集键会被所有的非聚集索引引用,作为书签来定位实际的数据行。聚集键实际就是一些列,它们构成了聚集索引和它们的数据值。这种特性有时也能导致SQL Server索引覆盖。
例如,假设suthors表在au_lname au_fname列上建立聚集索引,并有一个定义在au_id的非聚集索引。非聚集索引的每行都包含了与数据行对应的au_lname au_fname聚集键值。因为这个原因,下面查询将被非聚集索引覆盖:
- Sql代码
- select au_lname, au_fname
- from authors
- where au_id like '123%'
以上的相关内容就是对SQL Server索引覆盖(Index Covering)的介绍,望你能有所收获。
【编辑推荐】