索引初探(三)

由于前一篇写的有点匆忙很多地方不是很简单,这一片再描述一些概念和细节。

首先,我们都知道在数据库中的存储分为两种结构,一是堆;二是B树。堆的数据是没有排序也就没有结构性可言,我们可以简单理解为没有索引的表数据就是以堆的形式存在的。与之相对的,索引都是B树的形式存储,这样的话索引中数据是有序排列的。

其次,索引的结构上篇也是讲了,我们这里再根据非聚集索引的结构来对比一下聚集索引。

如图(官方提供的非聚集索引的结构图):

我们不难看出,上面红色标注的是非聚集索引,下面是聚集索引或者堆。由这个图来分析:

1.非聚集索引与聚集索引一样都是B树结构。

2.非聚集索引的叶子节点不是数据页,这样非聚集索引的叶子节点只包含键值和定位符(定位符,存在两种可能,如果表中有了聚集索引那么定位符就是个直接指向数据所在行的物理指针,如果有聚集索引,那么就是一个指向索引的聚集键)

3.与聚集索引不同,非聚集索引本身并不会改变数据页的存储模式。

本篇的重点:非聚集索引

非聚集索引包含了索引键列,包含列和书签。书签的值根据所在表是堆还是聚集索引既可以是RID也可以是聚集索引键,我们用两个图对比看一下一目了然。

上图显示的是非聚集索引在对上的实际结构,可以发现除了索引键值外,就是“RID”就是指向数据页的指针。

上图是非聚集索引在聚集索引上的结构,可以发现除去索引键值外,就是聚集索引键,查询数据时继续到索引中去寻找数据。

那么非聚集索引的优点:

1、因为在SQL Server中一页只是8K,页面空间有限,所以一行所包含的列数越少,它能保存的行就越多。非聚集索引通常不包含表中所有的列,它一般只包含非常少数的列。因此,一个页上将能包含比表行(所有的列)更多行的非聚集索引。

2、非聚集索引的另一个好处是,它有一个独立于数据表的结构,所以可以被放置在不同的文件组,使用不同的I/O路径,这意味着SQL Server可以并行访问索引和表,使查找更快速。

3、与聚集索引不同的时,一个表中可以有多个非聚集索引增加查询覆盖和交叉等等可以提高查询速度。

通过对聚集和非聚集索引的描述大概了解两种索引的基本结构和优缺点,下面根据其他人总结的什么情况下建立何种索引的一个常规方式:

                           使用聚集索引      使用非聚集索引
外键列                          应                      应
主键列                          应                      应
列经常被分组排序             应                     应
返回某范围内的数据          应                   不应
小数目的不同值               应                    不应
大数目的不同值               不应                   应
频繁更新的列                 不应                    应
频繁修改索引列              不应                    应
一个或极少不同值           不应                    应

总结:

      通过对索引的介绍和测试,我们发现索引能大幅提高查询的效率,但是同样相应的维护成本和性能消耗也是非常大的,这需要我们根据实际情况进行合理的设计。 当一个查询被传到数据引擎时,SQL Server可以通过三种路径获取数据来满足这个查询。

  1.     不需要访问表仅需要访问索引本身,这种情况必须是索引覆盖了请求所包含的列
  2.     使用索引键值去访问非聚集索引,然后使用书签访问非聚集索引所在表
  3.     全表扫描来获取数据

    了解这些基础概念接下来我们将从实际应用中去解决如何优化、如何合理化使用索引。

时间: 2024-12-26 13:03:39

索引初探(三)的相关文章

EF6.0+APS.NET MVC5.0项目初探三(code first实体映射到数据库)

到这里架构就搭建完了,该向里面填充东西的时候了,如上篇:EF6.0+APS.NET MVC5.0项目初探二(类库引用关系及说明) 第一步 :在需要添加EF的类库Domain.DbContext上右击->管理NuGet程序包->找到Entity FrameWork下载安装. 如图: 第二步:新建DbContext 第三步:在类库Domain.Entity上添加引用System.ComponentModel.DataAnnotations(用于验证的引用) 并新建实体类. 1 using Syst

Lucene.Net 2.3.1开发介绍 —— 三、索引(三)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(三) 3.Field配置所产生的效果 索引数据,简单的代码,只要两个方法就搞定了,而在索引过程中用到的一些类里最简单,作用也不小的就是Field,接下来看看Field的各项设置都会有什么样的效果. 代码 3.1 Code 1/**//// <summary> 2/// 索引数据 3/// </summary> 4private void Index() 5{ 6    Analyzer analyzer = new S

JavaScript初探三

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <ul id

JavaScript初探 三

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <input

lucene入门查询索引——(三)

1.用户接口(lucene不提供) 2.创建查询 3.执行查询 4.渲染结果: 5.过程分析 根据关键字查询索引库中的内容: 1)  创建IndexSearcher对象 2)  创建QueryParser对象 3)  创建Query对象来封装关键字 4)  用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准 5)  获取符合条件的编号 6)  用indexSearcher对象去索引库中查询编号对应的Document对象 7)  将Document

[Elasticsearch] 索引管理 (三) - 根对象(Root Object)

根对象(Root Object) 映射的最顶层被称为根对象.它包含了: 属性区域(Properties Section),列举了文档中包含的每个字段的映射信息. 各种元数据(Metadata)字段,它们都以_开头,比如_type,_id,_source. 控制用于新字段的动态探测(Dynamic Detection)的设置,如analyzer,dynamic_date_formats和dynamic_templates. 其它的可以用在根对象和object类型中的字段上的设置,如enabled,

sql server 索引总结三

一.非聚集索引维护 非聚集索引的行定位器值保持相同的聚集索引值,即使该聚集索引列物理上重新定位后,也是如此. 为了优化这个维护开销,SQL Server添加一个指向旧数据页的指针,以在页面分割之后指向新的数据页面,而不是更新所有相关非聚集索引的行定位器.这样,虽然降低了非聚集索引的维护开销,但是增加了从非聚集索引行到数据行的导航开销,因为添加了一个旧数据页面和信数据页面之间的连接.因此,将聚集索引作为行定位器降低了非聚集索引相关的开销. 二.定义书签查找 当一个查询请求不是优化器选择的非聚集索引

约束、索引、三范式

1.约束的定义: 约束(constraint):在建表时,为某些列添加一些特定的规则,这些规则称为约束.约束是在表上强制执行的数据校验规则保证数据库的数据满足某种用户的要求.添加约束之后,再往表中(插入.更新)数据时,如果数据不满足约束,则该条语句不能执行. 2.约束的分类: 2.1 非空约束 not null 非空约束确保字段值不允许为空非空约束只能在字段级定义 -- not null 非空约束 --添加了 not null的列的值不能为null,但可以是空格 create table tes

mongoDB常见的查询索引(三)

1. _id索引 _id索引是绝大多数集合默认建立的索引 对于每个插入的数据,MongoDB会自动生成一条唯一的_id字段. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 > db.jerome_2.collection.insert({x:2}) WriteResult({ "nInserted" : 1 }) > db.jerome_2.collection.getIndexes() [     {         "v&quo