SQLServer存储引擎——06.索引的遍历与维护

一、遍历

  索引树的每个节点都是一个页面。

  索引树有三种类型的节点:根节点、中间节点、叶子节点。

  (1) 根节点与中间节点一样,只包含下一层节点的入口值与入口指针,它们称为索引节点;

  (2) 叶子节点包含要遍历的数据,对聚集索引而言数据就是表中数据行,对非聚集索引数据是指索引列值和行书签。

  索引的遍历总是从根节点开始,即先根遍历,分为两种:索引扫描和索引查找。

  (1) 索引扫描,是指从索引树的根节点开始,对叶子节点逐个扫描,直至命中所有满足查找条件的数据;

  (2) 索引查找,是指从索引树的根节点开始,按查找值在索引节点中根据路由信息跳转,直至叶子节点以命中数据。

  B+树的深度通常小于等于3,计算如下:

  以聚集索引为例,简单计算如下:10个INT列宽度总和为40B,假设聚集索引树每一层为二叉,共三层,即2^0+2^1+2^2=1*(1-2^3)/(1-2)=7个页面,4个叶子节点,每个页面8060K可存储8060000/40=201500行,乘以4=806000行,如果是三叉、四叉,那么三层可存储上千万至亿行的数据,当然在数据量达到这个等级时,通常我们会选择表分区,那么B树深度就更不会突破三层了。

  所以索引查找的效率是很高的,在查询中应该努力构造索引查找,避免索引扫描。

二、插入

  2.1、页空间充足

  在已存在数据的表上,创建或重建索引时,可指定填充因子,即在索引树的每个节点上预留一定的空间,供表中后续增加的数据使用。但如果在创建表的时候就创建了索引,并指定了填充因子,这时的填充因子是无用的,数据库系统不会刻意去保留页面的空间。

  索引页面有剩余空间的情况如下图:

  参考上图,此时向索引树中插入一条索引键值为31的记录,步骤如下:

  (1)执行索引键值=31的查找操作,确定该新记录应该插入到叶子节点L2中。

  (2)检查L2上是否有足够的空间来存放当前记录,这里假设有足够的空间;

  (3)将记录45向后移动,插入索引键值为31的新记录。插入之后,10、30、31、45还是顺序的,如下图:

  2.2、页空间不足

  参考上图,此时再插入一条索引键值为32的记录,步骤如下:

  (1)执行索引键值=32的查找操作,确定该新记录应该插入到叶子节点L2中;

  (2)检查L2上是否有足够的空间来存放当前记录,这时发现没有足够的页空间,此时需要进行页面分裂;

  (3)向数据库系统申请一个新的页面L4,将L2的一半数据移到L4中,并重新链接叶子的左右节点,如下图:

  (4)此时,上层节点也需要生成一个新的叶子节点的指针。这里的上层节点即根节点,如果上层节点没有剩余空间的话,同样也需要进行分裂,这里有剩余空间,如下图:

  (5)因为当前记录的键值范围位于页分裂的后一半中,将索引键值为32的新记录插入到L4中,如果键值范围位于前一半,则插入到L2中。如果L4的空间不够存放键值为32的新记录,则L4会继续进行页分裂,这里假设空间足够,插入结束,如下图:

三、删除

  3.1、删除叶子节点中的记录

  参考上图5,删除索引键值为32的记录,步骤如下:

  (1)执行索引键值=32的查找操作,确定该记录在L4中;

  (2)将索引键值=32的记录标记为虚影,但并不立即释放空间,虚影记录可用于事务回滚、多版本等;

  (3)如果此时L4上的虚影记录空间被申请使用,虚影记录就会被擦除;

  (4)如果数据页面最后一条记录也被删除,数据页面会被回收;

  3.2、删除非叶子节点中的记录

  (1)索引节点中的指针被删除时并不是虚影记录,但同样也不释放空间,直到有新的指针插入时,才会进行空间压缩;

  (2)堆表中数据行被删除后,页空间不会被回收,即使是空闲分页也还是标识为分配状态,无法被其他对象使用;

  注:从理论上讲,在兄弟节点页面空闲空间都小于50%时,应该将兄弟节点合并,即分裂的逆操作,但这样可能带来的后果是更频繁的页面合并、分裂,成本更大,所以在数据库系统中通常不进行页面合并操作,除非rebuild/reorganize索引。

四、更新

  4.1、覆盖更新

  如果更新操作能够在页内进行原位键值替换,那么就进行覆盖更新。

  4.2、非覆盖更新

  无法进行覆盖更新时,更新操作被分解为删除和插入操作。

  如果非覆盖更新过程中,新的记录比较长,则会在页面分裂的过程中会带来数据行的移动:

  (1)聚集索引的移动对非聚集索引没有影响,因为非聚集索引中存储的是聚集索引的键值,分裂并不会改变键值;

  (2)堆表中的数据页分裂,会在原记录处留下一个前转指针,以告诉非聚集索引去哪里找新的记录;

  所以数据行的移动对非聚集索引都不会带来维护的成本,非聚集索引的维护成本来自书签的变化:

  (1)聚集索引的键值发生变化或被删除;

  (2)堆表中的数据行被删除。

--------------------------------------------------------------------------------------  
原文转自:http://qianzhang.blog.51cto.com/317608/1217346
--------------------------------------------------------------------------------------

时间: 2024-07-31 14:25:33

SQLServer存储引擎——06.索引的遍历与维护的相关文章

SQLServer存储引擎——索引的结构和分类

5. SQLServer存储引擎——索引的结构和分类 关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有数据页在磁盘上是如何组织的呢?分两种情况: 一是数据页间无序.随机地存储在磁盘上,这样的表叫做堆表(表上无聚集索引): 二是数据页间按某个表字段的值有序地存储在磁盘上,这样的表做索引组织表(表上有聚集索引). 索引是什么?从物理结构上可分为两种:聚集索引和非聚集索引.将表中的数据有序地组织起来的索引

SQLServer存储引擎——内存

SQLServer存储引擎之内存篇: (1)SQL SERVER 内存结构       SQL SERVER 内存结构简图 SQL SERVER 内存空间主要可分为两部分: (1.1)可执行代码(Executable Code) 主要包括SQL SERVER 实例中的一些EXE和DLL文件 (0)SQL SERVER 引擎(SQL SERVER ENGINE),SQL SERVER 数据库的主程序: (1)服务端网络库(SERVER NET-LIBRARY),用于与客户端网络库通讯,将TDS包交

MySQL存储引擎以及索引原理

一.MySQL存储引擎:MySQL将数据用各种不同的技术存储在文件中,这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.这些不同的技术以及配套的相关功能在 mysql中被称作存储引擎(也称作表类型).建表时,选择合适的存储引擎很重要,如果到后期再更换将会很麻烦.存储引擎是基于表的,而非数据库. 个人理解:存储引擎是某张表存储数据.如何为存储的数据建立索引和更新.查询数据库等技术的实现方法集合及约束.常见的存储引擎如下图: 这里,先总结常用的三种存储

MySQL存储引擎,索引及基本优化策略

存储引擎 与Oracle, SQL Server这些数据库不同,MySQL提供了多种存储引擎.什么是存储引擎?存储引擎其实就是一套对于数据如何存储,查询,更新,建立索引等接口的实现.不同存储引擎特性有所不同,我们根据需要进行选择,比如包含ETL操作的OLTP(联机交易处理)项目中我们通常选择InnoDB,而对于读操作较多几乎没有写操作的OLAP(联机分析处理)则选MyISAM的更多.因此并不是大家都用环境相似,同一版本的MySQL,能够使用的特性就是一致的.在MySQL终端中查看支持的存储引擎,

Mysql的存储引擎和索引

2 Mysql的存储引擎和索引 可以说数据库必须有索引,没有索引则检索过程变成了顺序查找,O(n)的时间复杂度几乎是不能忍受的.我们非常容易想象出一个只有单关键字组成的表如何使用B+树进行索引,只要将关键字存储到树的节点即可.当数据库一条记录里包含多个字段时,一棵B+树就只能存储主键,如果检索的是非主键字段,则主键索引失去作用,又变成顺序查找了.这时应该在第二个要检索的列上建立第二套索引.  这个索引由独立的B+树来组织.有两种常见的方法可以解决多个B+树访问同一套表数据的问题,一种叫做聚簇索引

SQLServer存储引擎——日志

3. SQLServer存储引擎之日志篇 (3.1)日志结构 (3.1.1)物理日志 (0)物理日志即数据库的.ldf文件, 当然后缀名是可以自定义的,默认是.ldf (1)一个SqlServer数据库,可以定义多个物理日志文件,SQL Server逻辑上把他们当作一个整体,顺序写入日志记录,用完第一个,再用下一个:即第一个日志文件的当前空间,如果没有可分配的VLF时,就会使用下一个日志文件的VLF,直到最后一个日志文件也没有可分配的VLF时,会重新回到第一个日志开始增长:VLF的使用如下图:

InnoDB 存储引擎之索引和优化

数据库优化可以说是后台开发中永恒的话题,数据库的性能通常是整个服务吞吐量的瓶颈之所在. 索引概述InnoDB中的表都是按照主键顺序组织存放的,这种组织方式称之为索引组织表,对比于MyISAM的表组织方式.在InnoDB中每张表都必须有一个主键,如果在创建表的时候没有显式定义主键,则InnoDB首先会判断表中是否有非空的唯一索引,如果有则将该列作为主键:否则InnoDB会自动创建一个6字节大小的指针作为主键.除主键之外,InnoDB还可以有辅助索引,而辅助索引页中仅仅存放键值和指向数据页的偏移量,

(3.8)存储引擎--索引的遍历与维护

一.遍历 索引树的每个节点都是一个页面. 索引树有三种类型的节点:根节点.中间节点.叶子节点. (1) 根节点与中间节点一样,只包含下一层节点的入口值与入口指针,它们称为索引节点: (2) 叶子节点包含要遍历的数据,对聚集索引而言数据就是表中数据行,对非聚集索引数据是指索引列值和行书签. 索引的遍历总是从根节点开始,即先根遍历,分为两种:索引扫描和索引查找. (1) 索引扫描,是指从索引树的根节点开始,对叶子节点逐个扫描,直至命中所有满足查找条件的数据: (2) 索引查找,是指从索引树的根节点开

mysql中常见的存储引擎和索引类型

存储引擎 1.      定义 存储引擎说白了就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据等技术的实现方法.因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和操作此表的类型). 在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的.而MySql数据库提供了多种存储引擎.用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需要编写自己的存储引擎. 2.      存储引擎的类型及特点