《SQL Server企业级平台管理实践》读书笔记——SQL Server中数据文件空间使用与管理
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中数据文件空间使用与管理的更多相关文章
- [读书笔记]SQLSERVER企业级平台管理实践读书笔记01
1. SQLSERVER信息收集 SQLDIAG 使用界面 C:\Users\Administrator>sqldiag2018/01/02 08:13:26.10 SQLDIAG Collec ...
- [读书笔记]SQLSERVER企业级平台管理实践读书笔记02
记录一下 这一块 join的理解了 再完善过来. 1. Statistics的用法: 清空执行计划用的命令 dbcc freeproccache 清空buffer pool 里面的缓存命令 dbcc ...
- 读书笔记--SQL必知必会18--视图
读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...
- Spark调度管理(读书笔记)
Spark调度管理(读书笔记) 转载请注明出处:http://www.cnblogs.com/BYRans/ Spark调度管理 本文主要介绍在单个任务内Spark的调度管理,Spark调度相关概念如 ...
- 《SQL Server企业级平台管理实践》读书笔记——SQL Server中关于系统库Tempdb总结
Tempdb系统数据库是一个全局资源,可供连接到SQL Server实例的所有用户使用. 存储的内容项: 1.用户对象 用户对象由用户显示创建.这些对象可以位于用户会话的作用域中,也可以位于创建对象所 ...
- 《SQL Server企业级平台管理实践》读书笔记——SQL Server中收缩数据库不好用的原因
数据库管理员有时候需要控制文件的大小,可能选择收缩文件,或者把某些数据文件情况以便从数据库里删除. 这时候我们就要使用到DBCC SHRINKFILE命令,此命令的脚本为: DBCC SHRINKFI ...
- 《SQL Server企业级平台管理实践》读书笔记——SQL Server数据库文件分配方式
1.文件分配方式以及文件空间检查方法 最常用的检查数据文件和表大小的命令就是:sp_spaceused 此命令有三个缺陷:1.无法直观的看出每个数据文件和日志文件的使用情况.2.这个存储过程依赖SQL ...
- 《SQL Server企业级平台管理实践》读书笔记——几个系统库的备份与恢复
master数据库 master作为数据库的主要数据库,记录着SQL Server系统的所有系统级信息,例如登录用户.系统配置设置.端点和凭证以及访问其他数据服务器所需要的信息.master数据库还记 ...
- 《Microsoft SQL Server企业级平台管理实践》笔记
- 页是 SQL Server 中数据存储的基本单位,大小为 8KB. - 区是空间管理的基本单位,8个物理上连续的页的集合(64KB). - 页的类型包括: 1. Data 2. Index 3. ...
随机推荐
- C#函数式程序设计之代码即数据
自3.5版本以来,.NET以及微软的.NET语言开始支持表达式树.它们为这些语言的某个特定子集提供了eval形式的求值功能.考虑下面这个简单的Lambda表达式: Func<int, int, ...
- 请求参数到表述层的类型转换——Struts2
一.简介 说明:HTTP 协议传输数据没有类型的概念,在服务器端是通过 request.getParameter().request.getParameterValue() 方法得到请求参数为 Str ...
- DataBase --- Intellij IDEA 14.1.4使用Java连接SQL Server教程
Java连接数据库的方法大体分为两种:正向连接和反向连接.反向连接需要编译器提供相关的插件来支持,目前主流的java IDE都支持反向连接.这里主要对正向连接做一个经验总结. 一.数据库的配置 1.新 ...
- AC自动机 - 多模式串的匹配运用 --- HDU 3065
病毒侵袭持续中 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=3065 Mean: 略 analyse: AC自动机的运用. 这一题 ...
- .net中清理内存,清理占用内存方式方法
#region 内存回收 [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize") ...
- JS实现注销功能
JS实现注销功能,代码如下: <script> window.history.forward(1); </script> 这个代码的用法就是: 比如,我们此时有两个页面:Log ...
- 泛函编程(11)-延后计算-lazy evaluation
延后计算(lazy evaluation)是指将一个表达式的值计算向后拖延直到这个表达式真正被使用的时候.在讨论lazy-evaluation之前,先对泛函编程中比较特别的一个语言属性”计算时机“(s ...
- jquery fadeOut 异步
1. 概述 jquery实现动画效果的函数使用起来很方便,不过动画执行是异步的, 所以要把自定义的操作放在回调函数里. 2. example <html> <body> < ...
- [转载]拜占庭问题深入讨论 from http://bitkan.com/news/topic/14011
拜占庭将军问题深入探讨 了解过比特币和区块链的人,多少都听说过拜占庭将军问题,或听说过比特币(或区块链)的一个重要成就正是解决了拜占庭将军问题.但真正明白这个问题的人并不多,甚至知道这个问题实质的人都 ...
- 总结一下SQL的全局变量
SQL Server 2008中的全局变量及其用法 T-SQL程序中的变量分为全局变量和局部变量两类,全局变量是由SQL Server系统定义和使用的变量.DBA和用户可以使用全局变量的值,但不能自己 ...