SQL Server 索引和表体系结构(二)
转自:http://www.cnblogs.com/chenmh
非聚集索引
概述
对于非聚集索引,涉及的信息要比聚集索引更多一些,由于整个篇幅比较大涉及接下来的要写的“包含列的索引”,“索引碎片”等一些知识点,可能要结合起来阅读理解起来要更容易一些。非聚集索引和聚集索引一样都是B-树结构,但是非聚集索引不改变数据的存储方式,所以一个表允许建多个非聚集索引;非聚集索引的叶层是由索引页而不是由数据页组成,索引行包含索引键值和指向表数据存储位置的行定位器,
既可以使用聚集索引来为表或视图定义非聚集索引,也可以根据堆来定义非聚集索引。非聚集索引中的每个索引行都包含非聚集键值和行定位符。此定位符指向聚集索引或堆中包含该键值的数据行。
正文
- 单个分区中的非聚集索引结构

非聚集索引 Index_id>1 可以结合语句查询

SELECT o.name AS table_name,p.index_id, i.name AS index_name , au.type_desc AS allocation_type, au.data_pages, partition_number,p.rows,
x.first_page,x.root_page,x.first_iam_page,x.filegroup_id,x.total_pages,x.used_pages
FROM sys.allocation_units AS au
JOIN sys.partitions AS p ON au.container_id = p.partition_id
JOIN sys.objects AS o ON p.object_id = o.object_id
JOIN sys.indexes AS i ON p.index_id = i.index_id AND i.object_id = p.object_id
join sys.system_internals_allocation_units as x on au.container_id=x.container_id
ORDER BY o.name, p.index_id;

非聚集索引行中的行定位器或是指向行的指针,或是行的聚集索引键,如下所述:
- 如果表是堆(意味着该表没有聚集索引),则行定位器是指向行的指针。该指针由文件标识符 (ID)、页码和页上的行数生成。整个指针称为行 ID (RID)。
如果表有聚集索引或索引视图上有聚集索引,则行定位器是行的聚集索引键。如果聚集索引不是唯一的索引,SQL Server 将添加在内部生成的值(称为唯一值)以使所有重复键唯一。此四字节的值对于用户不可见。仅当需要使聚集键唯一以用于非聚集索引中时,才添加该值。SQL Server 通过使用存储在非聚集索引的叶行内的聚集索引键搜索聚集索引来检索数据行。
- 非聚集索引与聚集索引相比:
A)叶子结点并非数据结点
B)叶子结点为每一真正的数据行存储一个“键-指针”对
C)叶子结点中还存储了一个指针偏移量,根据页指针及指针偏移量可以定位到具体的数据行。
D)类似的,在除叶结点外的其它索引结点,存储的也是类似的内容,只不过它是指向下一级的索引页的。
聚集索引是一种稀疏索引,数据页上一级的索引页存储的是页指针,而不是行指针。而对于非聚集索引,则是密集索引,在数据页的上一级索引页它为每一个数据行存储一条索引记录。

注意:上图中的数据页是聚集索引或者堆数据行,而不是非聚集索引的数据页,在非聚集索引中不存在数据页,非聚集索引中的叶子层和根节点与中间节点有点不同,它的指针是指向数据行,且如果非聚集索引如果是包含列索引,那么包含列仅仅存储在叶级别,而键值可以存储在所有级别,这块会在接下来的包含列索引中讲述。
对于根与中间级的索引记录,它的结构包括:
A)索引字段值
B)RowId(即对应数据页的页指针+指针偏移量)。在高层的索引页中包含RowId是为了当索引允许重复值时,当更改数据时精确定位数据行。
C)下一级索引页的指针
对于叶子层的索引对象,它的结构包括:
A)索引字段值
B)RowId
由于索引建值存储在索引页中,所以检索单独的索引键值效率是很高的,因为不需要定位到数据页在索引页中就能找到数据,对于当个字段建索引非聚集索引所占的空间要小于聚集索引,因为非聚集索引不需要存储数据行,对于建全覆盖索引除外。
- 非聚集索引列的选择
- 同样非聚集索引避免选择宽列,这点与聚集索引一样。
- 包含经常包含在查询的搜索条件(例如返回完全匹配的 WHERE 子句)中的列
- 经常作为JOIN 或 GROUP BY 子句
- 尽量避免使用组合列建索引,除非组合列在where中有使用,否则可以用包含列索引替代组合索引,选择组合字段做索引,组合字段的第一个字段选择很重要,第一个字段一定要经常被使用的字段,例如AB字段作为组合字段,当WHERE用A字段作为检索条件的时候,查询会使用索引查找;当你使用B作为WHERE的检索条件的时候,查询使用的是索引扫描,虽然我们不能绝对肯定查找的效率就一定比扫描要好,但是这也是告诉我们要合适的选择索引列,甚至的列之间的先后顺序。
- 大量非重复值,如姓氏和名字的组合(前提是聚集索引被用于其他列)。不要选择例如性别这种重复值多的列,这种情况表扫描比查找效率会更高,所以有时候当我们用查询计划分析时不一定扫描就一定比查找就要差,我们要根据实际情况去分析问题。
- 覆盖查询。
当索引包含查询中的所有列时,性能可以提升。查询优化器可以找到索引内的所有列值;不会访问表或聚集索引数据,这样就减少了磁盘 I/O 操作。使用具有包含列的索引来添加覆盖列,而不是创建宽索引键。有关详细信息,请参阅具有包含列的索引。
如果表有聚集索引,则该聚集索引中定义的列将自动追加到表上每个非聚集索引的末端。这可以生成覆盖查询,而不用在非聚集索引定义中指定聚集索引列。例如,如果一个表在 C 列上有聚集索引,则 B 和 A 列的非聚集索引将具有其自己的键值列 B、A 和 C
世界上没有绝对完美的事情,索引也是一样,给我们带来查询效率的同时也会有弊端
- 对表编制大量索引会影响 INSERT、UPDATE、DELETE 和 MERGE 语句的性能,因为当表中的数据更改时,所有索引都须进行适当的调整
总结
这篇文章更重要的是讲述索引的存储结构和查找方式,没有讲述索引的一些基本概念和语句的写法,网上有很多写的很好这方面的文章。希望写这篇文章能给大家带来帮助,文章中有一些内容是从别的作者哪里拷贝过来的,因为我觉得原作者(KissKnife)在这方面已经讲述的非常到位,所以借鉴了一下,同样如果文章中有讲述的不合理的地方还望大家提出。
SQL Server 索引和表体系结构(二)的更多相关文章
- SQL Server 索引和表体系结构(聚集索引)
聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在各个网站上面也有很多关于这方面写的不错的文章,我写这篇文章的目的也是为了将所有的知识点尽可能的组 ...
- SQL Server 索引和表体系结构(一)
转自:http://www.cnblogs.com/chenmh/p/3780221.html 聚集索引 概述 关于索引和表体系结构的概念一直都是讨论比较多的话题,其中表的各种存储形式是讨论的重点,在 ...
- SQL Server 索引和表体系结构(非聚集索引)
非聚集索引 概述 对于非聚集索引,涉及的信息要比聚集索引更多一些,由于整个篇幅比较大涉及接下来的要写的“包含列的索引”,“索引碎片”等一些知识点,可能要结合起来阅读理解起来要更容易一些.非聚集索引和聚 ...
- SQL Server 索引和表体系结构(包含列索引)
包含列索引 概述 包含列索引也是非聚集索引,索引结构跟聚集索引结构是一样,有一点不同的地方就是包含列索引的非键列只存储在叶子节点:包含列索引的列分为键列和非键列,所谓的非键列就是INCLUDE中包含的 ...
- SQL Server 索引和表体系结构(三)
转自:http://www.cnblogs.com/chenmh/p/3785285.html 包含列索引 概述 包含列索引也是非聚集索引,索引结构跟聚集索引结构是一样,有一点不同的地方就是包含列索引 ...
- 7、SQL Server索引、表压缩
索引 什么是索引? 索引是一种磁盘上的数据结构,建立在表或视图的基础上.使用索引可以使数据的获取更快更高校,也会影响其他的一些性能,如插入或更新等. 索引主要分为两种类型:聚集索引和非聚集索引. 字典 ...
- 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效
数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...
- SQL Server索引总结二
从CREATE开始 通过显式的CREATE INDEX命令 在创建约束时作为隐含的对象 随约束创建的隐含索引 当向表中添加如下两种约束之一时,就会创建隐含索引. 主键约束(聚集索引) 唯一约束(唯一索 ...
- SQL Server 索引的图形界面操作 <第十二篇>
一.索引的图形界面操作 SQL Server非常强大的就是图形界面操作.关于索引方面也一样那么强大,很多操作比如说重建索引啊,查看各种统计信息啊,都能够通过图形界面快速查看和操作,下面来看看SQL S ...
随机推荐
- Oracle 10046 trace文件分析
生成10046 trace文件: SQL> create table t10046 as select * from dba_objects; Table created. SQL> se ...
- 【转】Java多线程编程中易混淆的3个关键字( volatile、ThreadLocal、synchronized)总结
概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...
- 链表操作,空间复杂度要求为O(1)
对于O(1)的空间复杂度要求,不能对链表进行复制等操作,双指针法对处理该类问题比较有效. 同时由于链表头结点的特殊性,可以考虑引入一个空的头结点来辅助操作.
- CSS3的文字阴影—text-shadow
text-shadow还没有出现时,大家在网页设计中阴影一般都是用photoshop做成图片,现在有了css3可以直接使用text-shadow属性来指定阴影. 这个属性可以有两个作用,产生阴影和模糊 ...
- Lintcode: Previous Permuation
Given a list of integers, which denote a permutation. Find the previous permutation in ascending ord ...
- 转:python webdriver API 之简单对象的定位
对象(元素)的定位和操作是自动化测试的核心部分,其中操作又是建立在定位的基础上的,因此元素定位就显得非常重要. (本书中用到的对象与元素同为一个事物)一个对象就像是一个人,他会有各种的特征(属性) , ...
- 浅谈thinkphp中将字符串转换成json数组的方法
这是一部分代码: $client = M("Client");$data = $client->where('user_id ='.$user_id)->select( ...
- 创建一个web Test Plan
1.添加ThreadGroup (1).线程组界面解析: 线程数:虚拟用户的个数 Ramp-up Period:开启每个用户的延迟时间,如果有5个虚拟用户,Ramp-up Period值是5,Jmet ...
- Andriod环境搭建
安卓是一款现在在移动端十分流行的系统,本人出于好奇心,希望彻底了解安卓的开发技. 首先了解一下安卓的系统构架,安卓大致分为四层架构,五块区域: 1.Linux内核层 Andriod是基于Linux2. ...
- bzoj4547 小奇的集合
当序列中最大和次大都是负数的时候,其相加会是一个更小的负数,因此答案为(Σai)+(m1+m2)*k,如果最大是正数次大是负数,那么一直相加直到两个数都为正数,当最大和次大都是正数时,做一下矩阵乘法即 ...