1、表和索引存储结构

在SQL Server2005以前,一个表格是以一个B树或者一个堆(heap)存放的。每个B树或者堆,在sysindexes里面都有一条记录相对应。SQL Server2005以后,引入了分区表的概念(Table Partition),在存储组织上,现有的分区基本上替代了原来表格的概念,原先表的概念成为了一个逻辑概念。一个分区就是一个B树或者一个堆。而一张表格则是一个到多个分区的组合。

1.1用B树存储于聚集索引的表数据页

如果一个表格上有聚集索引(Clustered Index),数据行将基于聚集索引键按顺序存储。聚集索引按B树索引结构来实现,B树索引结构支持基于聚集索引键值对行快速检索。数据页面之间用双向链表,紧密相连。

1.2堆是没有聚集索引的表

如果表格上没有聚集索引,数据行将不按任何的顺序存储,数据页也没有任何特殊的顺序。数据页之间没有链表链接。

1.3非聚集索引

非聚集索引与聚集索引有一个相似的B树索引结构。不同的是,非聚集索引不影响数据行的顺序。叶级别仅包含索引行,没有完整的数据。每个索引行包含非聚集索引键值和行定位符。定位符指向(在另一个B树或者堆中)包含键值的数据行。非聚集索引本身也会占用一些数据页。这些页面以双向链表相连。

sys.partitions为表和索引提供一个对象,每个对象占据一行信息,其中分为以下几类:

1、index_id=0,这种行记录的是堆表信息

sys.system_internals_allocation_units中的first_iam_page列指向指定分区中堆数据页i聚合的IAM链。因为这些页没有连接,不可能从第一页找到下一页,所以SQL Server只能使用IAM页查找数据页集合中的每一页。

2、index_id=1,表示表或视图的聚集索引

sys.system_internals_allocation_units中的root_page列指向指定分区内聚集索引B树的顶端。SQL Server使用索引B树链表能够从顶端页面查找到分页中的每个数据页。

3、index_id>1,为表或视图创建的非聚集索引

sys.system_internals_allocation_units中的root_page列指向指定分区内非聚集索引B树的顶端。

如果存在LOB列(image、varchar(max)、text)的每个表在sys.partitions中也另外再有一行,其index_id>250,用以管理LOB页面。

first_iam_page列指向管理LOB_DATA分配单元中的页的IAM页链。

总之,从一个对象Index_id就能判断出它是什么类型的存储方式,如果是0,据说明这张表没有聚集索引;如果是1,就是聚集索引页面;如果大于250,就是text或image字段;如果在2——250之间,就是非聚集索引页面。

堆结构

堆是不包含聚集索引的表。SQL Server使用“索引分配映射(IAM)”页将堆的页面联系在一起。堆的特点有以下几个:

1、堆内的数据页和行没有任何特定的顺序。

在一个堆里的数据完全是随机存放的。而且SQL Server也假设数据之间没有任何联系。

2、页面也不连接在一起

数据页之间唯一的逻辑连接是记录在IAM页内的信息。页面与页面之间也没有什么紧密的联系。

3、堆中的行一般不按照插入的顺序返回

因为IAM按数据页在数据文件内存在的顺序标示他们,所以这意味着堆扫描会沿每个文件进行。而不是按这些行的插入顺序,或者任何逻辑上的顺序。

下图,表现了SQL Server数据库引擎如何使用IAM页检索具有单个分区的堆中的数据行。

可以看到,SQL Server对堆的管理师比较简单的。在算法能力上也是比较脆弱的。不谈性能,光从数据存储管理上来讲,用堆去管理一个超大的表格是比较吃力的。所以在SQL Server里对于所有大的、经常使用的表格上都建立聚集索引。因为聚集索引会避免很多问题。

聚集索引结构

在SQL Server中,索引是按B树结构进行组织的。索引B树种的每一页称为一个索引节点。B树的顶端节点称为根节点。索引中的底层节点称为叶节点。根节点与叶节点之间的任何索引级别统称为中间级。每个索引行包含一个键值和一个指针,该指针指向B树上某一中间页或页级索引中的某个数据行。每级索引张的页均被链接在双向链表中。

数据链内的页和行将按聚集索引键值进行排序。所有插入操作都在所插入行中的键值与现有行中的排序顺序相匹配时执行。B树页集合由sys.system_internals_allocation_units系统视图中的页指针来定位。

对于某个聚集索引,sys.system_internals_allocation_units中的root_page列指向该聚集索引某个特定分区的顶部。SQL Server将在索引中向下移动以查找与某个聚集索引键对应的行。为了查找键的范围,SQL Server将在索引中移动以查找该范围的起始键值,然后用向前或向后指针在数据页中进行扫描。为了查找数据页链的首页,SQL Server将从索引的根节点沿最左边的指针进行扫描。

相对于堆,聚集索引的特点有以下几个:

1、堆内的数据页和行有严格的顺序。

聚集索引保证了表格的数据按照索引行的顺序排列。而且SQL Server知道这种顺序关系。

2、页面链接在一起。页面与页面联系紧密。

3、树种的行一般能够按照索引列的顺序返回。

所以从这几点来看,建立B树以后,SQL Sever对数据页的管理能够更加快速有效,有些发生在堆上的问题就不容易发生在B树上,性能高出很多

非聚集索引结构

非聚集索引与聚集索引具有相同的B树结构,他们之间的显著差别在于以下两点:

1、基础表的数据行不按非聚集键的顺序排序和存储

2、非聚集索引的页层是由索引页面不是由数据页组成

3、建立非聚集索引的表可以是一个B树,也可以是一个堆。

4、如果表示堆(意味着该表没有聚集索引),则行定位器是指向行的指针。该指针由文件标识符(ID)、页码和页上的行数生成。整个指针称为行ID(RID)。

5、如果表没有聚集索引或索引视图上有聚集索引,则行定位器是行的聚集索引键。如果聚集索引不是唯一的索引,SQL Server将添加在内部生成的值(称为唯一值)以使所有重复键唯一。SQL Server通过使用存储在非聚集索引的叶行内的聚集索引键搜索聚集索引来检索数据行。

所以非聚集索引不会去改变或改善数据页的存储方式。它的B数结构只针对自己的索引页面。如果问题是堆的特性导致的,加一个非聚集索引不能带来根本的改善。

对于表格建立聚集索引不会增加表格的大小,而增加非聚集索引就会增加空间,但是如果在一个经常变化的表格建立聚集索引,会容易遇到页拆分(page split),所以尽力聚集索引会影响性能。基于这种考虑,很多设计者不愿意在SQL Server的表格中建立聚集索引,但是一张不建立索引的表格性能是非常差的,所以就增加了非聚集索引,以期望得到好的性能。

但是这这种方案是一种浪费空间、性能也不一定好的设计,为此SQL Server2005做了个比较,得出的结论是:有聚集索引的表格在Select 、Update、Delete这些动作性能有很大的提升,更重要的是在Insert这一项上,两者没有什么差别。并没有出现聚集索引影响Insert速度的现象。所以再次强烈建议,在一个大的表格上一定要建立一个聚集索引。

DELETE和TRUNCATE之间的区别

1、DELETE命令并不能完全释放表格或索引的数据结构以及他们申请的页面,尤其在堆表上。在SQL Server2005以后的版本中树结构的数据对于页释放做的更好一点,但是也不能完全释放。而TRUNCATE就能完全释放掉

2、所用事务日志空间较少,因为DELETE语句每次删除一行,并在事务日志中为所删除的每行记录一个项,TRUNCATE TABLE通过释放用于存储数据的数据页来删除数据,并且在事务日志中只记录这个动作,而不记录每一行。

3、使用的锁通常较少,当使用行锁执行Delete语句时,将锁定表中各行以便删除,TRUNCATE TABLE始终锁定表和页,而且速度更快

4、表中将毫无例外的不保留任何页,执行DELETE语句后,表仍会包含空页。例如,必须至少一个排他(LCK_M_X)表锁,才能释放堆中的空页。如果执行删除操作时没有使用表锁,表(堆)中将包含许多空页。对于索引、删除操作会留下一些空页,尽管这些页会通过后台清楚迅速释放。

TRUNCATE TABLE删除表中的行的所有行,但表结构以及其列、约束、索引等保持不变。若删除表定义以及其数据,使用Drop table语句。

所以对于像及时的删除数据,然后释放空间,可以采用的方法有:

1、在表格建立聚集索引

2、如果所有数据都不要了,要使用TRUNCATE TABLE而不是delete

Delete 不能完全释放空间,会不会造成空间泄露了呢?其实不用担心,虽然没有将这些页面释放掉,但是当表格插入新的数据的时候,这些页面会被重新使用的。所以这些页面并没有“泄露”掉,会留给SQL Server重用。

如果真的非要用DELETE语句,如果表有聚集索引,重建一下索引能释放掉出这些空间,但是如果没有,可以重建一张新表,把数据从旧表中倒过去,然后删除旧表,释放空间;也可以在这种表上新建聚集索引,这样有点折腾,当然有时候也没必要非要把空间释放出来,可以等着新数据插入时,直接利用就行。

《SQL Server企业级平台管理实践》读书笔记——SQL Server中数据文件空间使用与管理的更多相关文章

  1. [读书笔记]SQLSERVER企业级平台管理实践读书笔记01

    1. SQLSERVER信息收集 SQLDIAG 使用界面 C:\Users\Administrator>sqldiag2018/01/02 08:13:26.10 SQLDIAG Collec ...

  2. [读书笔记]SQLSERVER企业级平台管理实践读书笔记02

    记录一下 这一块 join的理解了 再完善过来. 1. Statistics的用法: 清空执行计划用的命令 dbcc freeproccache 清空buffer pool 里面的缓存命令 dbcc ...

  3. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  4. Spark调度管理(读书笔记)

    Spark调度管理(读书笔记) 转载请注明出处:http://www.cnblogs.com/BYRans/ Spark调度管理 本文主要介绍在单个任务内Spark的调度管理,Spark调度相关概念如 ...

  5. 《SQL Server企业级平台管理实践》读书笔记——SQL Server中关于系统库Tempdb总结

    Tempdb系统数据库是一个全局资源,可供连接到SQL Server实例的所有用户使用. 存储的内容项: 1.用户对象 用户对象由用户显示创建.这些对象可以位于用户会话的作用域中,也可以位于创建对象所 ...

  6. 《SQL Server企业级平台管理实践》读书笔记——SQL Server中收缩数据库不好用的原因

    数据库管理员有时候需要控制文件的大小,可能选择收缩文件,或者把某些数据文件情况以便从数据库里删除. 这时候我们就要使用到DBCC SHRINKFILE命令,此命令的脚本为: DBCC SHRINKFI ...

  7. 《SQL Server企业级平台管理实践》读书笔记——SQL Server数据库文件分配方式

    1.文件分配方式以及文件空间检查方法 最常用的检查数据文件和表大小的命令就是:sp_spaceused 此命令有三个缺陷:1.无法直观的看出每个数据文件和日志文件的使用情况.2.这个存储过程依赖SQL ...

  8. 《SQL Server企业级平台管理实践》读书笔记——几个系统库的备份与恢复

    master数据库 master作为数据库的主要数据库,记录着SQL Server系统的所有系统级信息,例如登录用户.系统配置设置.端点和凭证以及访问其他数据服务器所需要的信息.master数据库还记 ...

  9. 《Microsoft SQL Server企业级平台管理实践》笔记

    - 页是 SQL Server 中数据存储的基本单位,大小为 8KB. - 区是空间管理的基本单位,8个物理上连续的页的集合(64KB). - 页的类型包括: 1. Data 2. Index 3. ...

随机推荐

  1. 基于HTML5实现的Heatmap热图3D应用

    Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. 已有众多文章分享了生成Heatmap热图原 ...

  2. (5)分布式下的爬虫Scrapy应该如何做-windows下的redis的安装与配置

    软件版本: redis-2.4.6-setup-64-bit.exe — Redis 2.4.6 Windows Setup (64-bit) 系统: win7 64bit 本篇的内容是为了给分布式下 ...

  3. JS 中 this上下文对象的使用方式

    JavaScript 有一套完全不同于其它语言的对 this 的处理机制. 在五种不同的情况下 ,this 指向的各不相同. 有句话说得很在理 -- 谁调用它,this就指向谁 一.全局范围内 在全局 ...

  4. ok6410 android driver(5)

    Test the android driver by JNI (Java Native Interface), In the third article, we know how to compile ...

  5. Requested registry access is not allowed(不允许所请求的注册表访问权)

    尝试创建自定义事件日志时,将会收到“Requested registry access is not allowed(不允许所请求的注册表访问权)”错误消息 EventLog.CreateEventS ...

  6. windows的host文件的位置和作用

    在Window系统中有个Hosts文件(没有后缀名),在Windows98系统下该文件在Windows目录,在Windows2000/XP系统中位于C:\Winnt\System32\Drivers\ ...

  7. C#获取url中参数键值对的方法

    方法如下: /// <summary> /// 遍历Url中的参数列表 /// </summary> /// <returns>如:(?userName=keley ...

  8. mongodb学习2---常用命令解析

    1,mongodb insert()和save()的相同点和区别区别:若新增的数据中存在主键 ,insert() 会提示错误,而save() 则更改原来的内容为新内容.insert({_id : 1, ...

  9. [性能] Bean拷贝工具类性能比较

    Bean拷贝工具类性能比较 引言 几年前做过一个项目,接入新的api接口.为了和api实现解耦,决定将api返回的实体类在本地也建一个.这样做有两个好处 可以在api变更字段的时候保持应用稳定性 可以 ...

  10. Play 可以做的 5 件很酷的事

    Play 可以做的 5 件很酷的事 本章译者:@Playframwork 通过 5 个实例,透视 Play 框架背后的哲学. 绑定 HTTP 参数到 JAVA 方法参数 用 Play 框架,在 Jav ...