SQL Server性能优化(7)理解数据库文件组织
一、基本单位“页”
SQL Server是用8KB的页来存储数据。物理I/O操作也是在页级执行。页的种类有很多,具体参考(MSDN)。我们关注更多的是数据页的结构,包括三部分:页头(96bytes)、数据区(数据行和可用空间)以及行偏移数组(槽,最少是7bytes):
为什么数据页的大小是8k,这有什么优缺点,有两篇文章解释的很好(数据页结构,坏的一面)。总结下,
a. 数据区大小 =(8192 - 页头96bytes+偏移数组7byte) = 8053bytes,这是一个页能分配给我们的数据使用的最大空间。我们的数据就一行一行的放在这写数据内部。
b. 如果我们一行数据包含两个int列,那一共可以存储 8053%(4+4)= 999.125,最后余7byte空间无法存入,也就是这这个页里浪费了7bytes。如
c. 果我们一行数据包含三列(一个int、一个char(4000)、一个char(100),共4104byte),那每个页只能存储一行,浪费了3 949bytes,很明显这不是一个好的数据库设计。
d. 可以利用free_space_in_bytes来查看页面空闲情况。
SELECT
DB_NAME(database_id),
SUM(free_space_in_bytes) / 1024 AS 'Free_KB'
FROM sys.dm_os_buffer_descriptors
WHERE database_id <> 32767
GROUP BY database_id
ORDER BY SUM(free_space_in_bytes) DESC
GO
e. 包含 varchar、nvarchar、varbinary 或 sql_variant 列的表不受此限制的约束。MSDN上有进一步解释行溢出数据超过 8 KB。
f. 要进一步了解数据页内部的结构,参考:http://www.cnblogs.com/woodytu/p/4484328.html
二、页的上层--“区”和分配映射表
区是管理空间的基本单位。一个区是八个物理上连续的页(即 64 KB)。这意味着 SQL Server 数据库中每 MB 有 16 个区。
由于历史原因,SQL Serve有两种类型的区:同一区、混合区。
混合区:区内的8个页,可以是不同的表、索引等。
统一区:区内的8个页,是同一个表、索引。
新建表的时候,先在混合区插入一条记录,当其占用的这个混合区的表或索引增长到 8 页时,将变成使用统一区进行后续分配,每次扩展84kb(8页)。问题是如何管理这两种分区?答案是GAM页和SGAM页。
1. 全局分配映射表(GAM: Global Allocation Map Pages)---为统一区管理服务
这是一个页,共64000位(8000bytes)的掩码位图(参考位图算法),用一个位管理一个byte管理4Gbyte。所以每隔4G的数据文件都要有一个GAM页进行管理(64000 * 64 /1024 /1024)。
2. 共享全局分配映射表(SGAM: Shared Global Allocation Map Pages)---为混合区管理服务
原理同全局分配映射表。
三、可用空间管理页面:PFS页(Page Free Space)
该页面用来跟踪一个文件中每一个特定的页面的利用率情况,是以页为单位的。一个文件中第二个页面(页码1,如下图)就是PFS页面,该页面的每个字节都记录了相应页面的分配情况、页面类型、是否IAM页、是否包含删除记录、以及空间利用率信息;PFS能够管理和跟踪8088个页面的使用情况,即接近64M的空间,以后每8088个页面将再出现一次(参考)。
PFS每个字节管理一个页面,字节结构为:
四、索引分配映射页:IAM页
主要用来标示 SQL Server 对象使用了哪些区。比如A表的非聚集索引B占用了 6、7、8、9 这4个区。这样,在再对此对象做更改的时候,能够快速的找到这4个区,更改文件。
当 SQL Server 数据库引擎必须在当前页中插入新行,而当前页中没有可用空间时,它将使用 IAM 和 PFS 页查找要将该行分配到的页,或者(对于堆或 Text/Image 页)查找具有足够空间容纳该行的页。分配的过程是:
1. 数据库引擎使用 IAM 页查找分配给分配单元的区。
2. 对于每个区,数据库引擎将搜索 PFS 页,以查看是否有可用的页。
每个 IAM 和 PFS 页覆盖大量数据页,因此一个数据库内只有很少的 IAM 和 PFS 页。这意味着 IAM 和 PFS 页通常位于内存中的 SQL Server 缓冲池中,所以能够很快找到它们。对于索引,新行的插入点由索引键设置。在这种情况下,不会出现上述搜索过程。
另外,一个 IAM 页可以映射的范围 4 GB,与 GAM 或 SGAM 页的范围相同。如果分配单元包含来自多个文件的区,或者超过一个文件的 4 GB 范围,那么一个 IAM 链中将链接多个 IAM 页。
五、已修改区域的管理(参考MSDN)
SQL Server 使用两个内部数据结构跟踪被大容量复制操作修改的区,以及自上次完整备份后修改的区。这些数据结构极大地加快了差异备份的速度。当数据库使用大容量日志恢复模式时,这些数据结构也可以加快将大容量复制操作记录至日志的速度。与全局分配图 (GAM) 和共享全局分配图 (SGAM) 页相同,这些结构也是位图,其中的每一位代表一个单独的区。 包括
1. 差异更改映射表 (DCM)
2. 大容量更改映射表 (BCM)
DCM 页和 BCM 页的间隔与 GAM 和 SGAM 页的间隔相同,都是 64,000 个区。在物理文件中,DCM 和 BCM 页位于 GAM 和 SGAM 页之后。
六、总结
通过以上介绍,我们大体知道了SQL Server物理文件的结构:
有一篇更深入的介绍http://www.cnblogs.com/woodytu/p/4495021.html
参考:索引概念分类:https://technet.microsoft.com/zh-cn/library/ms175049(v=sql.105).aspx
聚集索引结构:https://technet.microsoft.com/zh-cn/library/ms177443(v=sql.105).aspx
Sql Server 中 GAM、SGAM、PAM、IAM、DCM 和 BCM 的详解与区别
SQL Server 深入解析索引存储(上)
SQL Server 深入解析索引存储(中)
SQL Server 深入解析索引存储(下)
SQL Server性能优化(7)理解数据库文件组织的更多相关文章
- SQL SERVER性能优化综述
SQL SERVER性能优化综述 一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开发阶段的事情,而是在整个软件生命周期都需要注意,进行有效工作才能达到的.所以我希望按照软 ...
- SQL Server 性能优化之RML Utilities:快速入门(Quick Start)(1)
SQL Server 性能优化之RML Utilities:快速入门(Quick Start)(1) 安装Quick Start工具 RML(Replay Markup Language)是MS ...
- SQL Server 性能优化(一)——简介
原文:SQL Server 性能优化(一)--简介 一.性能优化的理由: 听起来有点多余,但是还是详细说一下: 1.节省成本:这里的成本不一定是钱,但是基本上可以变相认为是节省钱.性能上去了,本来要投 ...
- SQL Server 性能优化之——系统化方法提高性能
SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...
- 【SQL Server性能优化】删除大量数据的方法比较
原文:[SQL Server性能优化]删除大量数据的方法比较 如果你要删除表中的大量数据,这个大量一般是指删除大于10%的记录,那么如何删除,效率才会比较高呢? 而如何删除才会对系统的影响相对较小呢? ...
- 【SQL Server性能优化】运用SQL Server的全文检索来提高模糊匹配的效率
原文:[SQL Server性能优化]运用SQL Server的全文检索来提高模糊匹配的效率 今天去面试,这个公司的业务需要模糊查询数据,之前他们通过mongodb来存储数据,但他们说会有丢数据的问题 ...
- SQL Server性能优化与管理的艺术 附件下载地址
首先感谢读者们对鄙人的支持,购买了<SQL Server性能优化与管理的艺术>,由于之前出版社的一些疏忽,附件没有上传成功,再次本人深表歉意. 请需要下载附件的读者从下面链接下载,谢谢: ...
- SQL Server性能优化(6)查询语句建议
1. 如果对数据不是工业级的访问(允许脏读),在select里添加 with(nolock) ID FROM Measure_heat WITH (nolock) 2. 限制结果集的数据量,如使用TO ...
- SQL Server 性能优化详解
故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...
- SQL Server 性能优化实战系列(二)
SQL Server datetime数据类型设计.优化误区 一.场景 在SQL Server 2005中,有一个表TestDatetime,其中Dates这个字段的数据类型是datetime,如果你 ...
随机推荐
- js监听键盘触发按钮事件,回车提交表单
/*回车提交表单*/ $(document).keydown(function(event){ if(event.keyCode == 13){ //alert('你按下了Enter'); $(&qu ...
- 程序重复报more than 'max_user_connections' active connections问题解决
早晨,开发扔过来一个问题,截图如下: ums already has more than 'max_user_connections' active connections 查看数据库发现: 最大连接 ...
- 好文推荐系列---------(4)使用Yeoman自动构建Ember项目
好文原文地址:http://segmentfault.com/a/1190000000368881 我决定学习前端开发的效率工具Yeoman.本文将首先介绍Yeoman的基本情况,接着我们会使用Yeo ...
- MySQL 安装与使用(三)
操作系统:CentOS release 5.10 (Final) MySQL版本:5.1.72-community 占位学习与编辑中……
- 大压力下Redis参数调整要点
调整以下参数,可以大幅度改善Redis集群的稳定性: 为何大压力下要这样调整? 最重要的原因之一Redis的主从复制,两者复制共享同一线程,虽然是异步复制的,但因为是单线程,所以也十分有限.如果主从间 ...
- $.contains(a,b)
jQuery.contains()函数用于判断指定元素内是否包含另一个元素. 简而言之,该函数用于判断另一个DOM元素是否是指定DOM元素的后代. 该函数属于全局jQuery对象. 语法 jQuery ...
- Ng第十二课:支持向量机(Support Vector Machines)(二)
7 核函数(Kernels) 最初在“线性回归”中提出的问题,特征是房子的面积x,结果y是房子的价格.假设从样本点的分布中看到x和y符合3次曲线,那么我们希望使用x的三次多项式来逼近这些样本点.那么首 ...
- Windows 8创新之路——样章分享
在电脑里面躺了大约也有半年多的光景了. 在Windows 8.1还有不到一个月的时间里,将这些内容分享出来,也算是对得起自己那段时间的熬夜. 希望大家多提宝贵意见. 谢! 点击标题可浏览SkyDriv ...
- 第83讲:Scala中List的实现内幕源码揭秘
今天我们来学习一下scala的List的方法的内部源码的一些知识. 首先,take方法.take方法就是取列表的从第一个元素开始的前N个元素.如list.take(3),就是取list的前3个元素,返 ...
- python_列表、元组、字典、集合对比
列表.元组.字典.集合 列表.元组.字典.集合对比 比较项 列表 元组 字典 集合 类型名称 list tuple dict set 定界符 [] () {} {} 是否可变 是 否 是 是 是否有序 ...