第2/24周 页_SQL Server 中数据存储的基本单位
上周通过探讨SQL Server如何执行一个查询奠定了基础。我也在那里提到页是8kb的缓存。今天我们对页进行进一步集中探讨,从性能调优角度挖掘出更多的细节。
页是SQL Server的基础,在SQL Server里一切都与页有关。当我们想提高查询性能时,我们可以减少SQL Server指定查询所需页的读取。在第二个月当我们讨论索引时,我们发现其实索引的结构也是由页组成的。当你不知道页是什么的时候,你就不能对SQL Server进行调优和故障排除。
数据页结构
在SQL Server中页的大小始终是8kb的大小,页有不同的类型:数据页,索引页,系统页等等。今天我们对在SQL Server存储我们表数据的数据页进行更多细节的学习。一个数据页总是由三个部分组成:
- 页头(Page Header)
- 数据区(Payload)
- 行偏移数组(Row Offset Array)
在SQL Server中页头的始终是96 byte长(不受页的类型约束),这里存储着像Page ID,Object ID等页的大体信息。数据区是页中最有意思的部分,因为我们的记录就存在那里。SQL Server给你8192 bytes(8kb)的空间,其中8096 bytes是给数据区的。因此计算多少条记录刚好可以填满一个页是个很容易的事,直接拿8096除以记录长度即可(这里包含至少7 bytes的内部行开销)。当你把结果取整下,你就得到在一页里你可以存放多少条记录。
SQL Server中对页操作必须是整页读或写的,因此我们的目标总是希望在一页里存放尽可能多的记录。SQL Server不能从你存储里读页的一部分,或者把页的一部分写入存储。I/O操作始终最少都是在页级别完成的。
最后在页的底部你会看到被称作行偏移数组的东西。行偏移数组用2 bytes存储着每条记录在页里位置的偏移量。第一条记录始终开始与96的偏移,刚好紧接着页头。下图可以给你刚才介绍的数据页结构的概况认识。

深入解析数据页
我们来看一个简单的表定义:
CREATE TABLE Customers
(
FirstName CHAR(50) NOT NULL,
LastName CHAR(50) NOT NULL,
Address CHAR(100) NOT NULL,
ZipCode CHAR(5) NOT NULL,
Rating INT NOT NULL,
ModifiedDate DATETIME NOT NULL,
)
GO
对于这样一个表定义我们很容易计算出在一页里我们可以存放几条记录。这里记录的大小是224 bytes长(50+50+100+5+4+8+7)。8096 / 224 = 36.14,也就是说在一页你最多能存放36条记录。那其他剩余的空间——在这里是32 bytes(8096-224*36)就浪费掉了,因为数据页只能属于一个指定的数据库对象,且不能与其他对象共享。最坏的情况,当你的表定义了一条长度为4031bytes 的记录时,在每一页你都在浪费4029 bytes的空间。当你用像VARCHAR等变长类型定义字段时,情况会发生改变,因为SQL Server允许变长列存放在不同的页。
如果你想知道在你数据库设计后,每页有多少空间浪费掉,你可以通过下列动态管理视图(DMV)查询下缓冲池:sys.dm_os_buffer_descriptors 从这个动态管理视图(DMV)显示的每条记录都代表当前在缓存池里保存的每一页,当你在有大内存的机器上查询这个动态管理视图时要注意了,这个操作很耗内存。free_space_in_bytes 列告诉你当前页有多少空间是空闲的。下面这个查询可以告诉你在SQL Server里每个数据库有多少空间被浪费:
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
这个是我在系统里经常执行的查询(例如在做SQL Serve健康检查时),为了找出哪个数据库有糟糕的表设计。
小结
我希望这次性能调优培训可以帮你更好的理解SQL Serve中的数据页,而且它们对性能调优是多么重要。你也看到,专注于表设计与否将直接影响多少数据页给一个表使用。
如果你想知道关于数据页的更多细节信息,看下这个文章:SQL Server:理解数据页结构。
下周我们将探讨SQL Serve里区的更多细节,它们同样对我们很重要。
围观PPT:
0430_02页_SQL_Server中数据存储的基本单位.zip
第2/24周 页_SQL Server 中数据存储的基本单位的更多相关文章
- 第2周 页_SQL Server 中数据存储的基本单位
原文:第2周 页_SQL Server 中数据存储的基本单位 上周通过探讨SQL Server如何执行一个查询奠定了基础.我也在那里提到页是8kb的缓存.今天我们对页进行进一步集中探讨,从性能调优角度 ...
- 第3/24周 区_SQL Server中管理空间的基本单位
哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Server内核运行机制有了很好的认识.今天我会讲下SQL Server中的区管理,因为这是个很重要的话题,我们会在第23周 ...
- 第3周 区_SQL Server中管理空间的基本单位
原文:第3周 区_SQL Server中管理空间的基本单位 哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Server内核运行机制有了很好的认识.今天我会讲下SQL Se ...
- Android中数据存储(一)
国庆没有给国家添堵,没有勾搭妹子,乖乖的写着自己的博客..... 本文将为大家介绍Android中数据存储的五种方式,数据存储可是非常重要的知识哦. 一,文件存储数据 ①在ROM存储数据 关于在ROM ...
- Android中数据存储(三)——SQLite数据库存储数据
当一个应用程序在Android中安装后,我们在使用应用的过程中会产生很多的数据,应用都有自己的数据,那么我们应该如何存储数据呢? 数据存储方式 Android 的数据存储有5种方式: 1. Share ...
- Java基础知识强化之IO流笔记46:IO流练习之 把文本文件中数据存储到集合中的案例
1. 把文本文件中数据存储到集合中 需求:从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合. 分析: 通过题目的意思我们可以知道如下的一些内容, 数据 ...
- android中数据存储
android中数据存储 Android 中存储数据的方式有五种:SQLite数据库.文件存储.内容提供者.网络.SharedPreferences(Key----value)五种存储方式. ...
- Android中数据存储(四)——ContentProvider存储数据
目录(?)[+] 当一个应用程序在Android中安装后,我们在使用应用的过程中会产生很多的数据,应用都有自己的数据,那么我们应该如何存储数据呢? 数据存储方式 Android 的数据存储有5种方 ...
- 第十七周翻译-SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志
SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志 作者:Tony Davis,2012/01/27 翻译:赖慧芳 译文: 该系列 本文是Stairway系列的一部分:SQL ...
随机推荐
- Android(5)— Mono For Android 两个功能型外包
0.前言 距上一篇博文貌似很久了,其中原因种种,归根结底是自己没有坚持好,没有静下心来归纳总结,希望从这一刻起每个月坚持写两篇.(哈哈,突然想起老师说起一句话, 晚上在被窝里悄悄发誓好好学习,第二天涛 ...
- 异步CTP(Async CTP)为什么那样工作?
对异步CTP感兴趣有很多原因.异步CTP使异步编程比以前更加容易了.它虽然没有Rx强大,但是更容易学.异步CTP介绍了两个新的关键字,async和await.异步方法(或Lambda表达式)必须返回v ...
- 新浪微博UWP UI意见征求
各位园主,卑职最近在忙一些新浪微博UWP的事儿,其中有一些UI上的design和实现,拿出来见见公婆,请大家给个意见: 您是喜欢A还是B.麻烦直接回在评论区了,写A或B,愿意多写几句意见的更欢迎! 先 ...
- Java对象表示方式2:XStream实现对对象的XML化
上一篇文章讲到了使用Java原生的序列化的方式来表示一个对象.总结一下这种对象表示方式的优缺点: 1.纯粹的Java环境下这种方式可以很好地工作,因为它是Java自带的,也不需要第三方的Jar包的支持 ...
- MSBuild 中的 PropertyGroup、ItemGroup 和 ItemMetadata
在软件项目不断的进展中,MSBuild 脚本可能几个月都不会被修改,因为通常编译和发布的目录是不经常变化的. 但,一旦某天你需要修改了,看到那一堆 $(Something). @(Something) ...
- dijit样式定制之TextBox(一)
参考资料:http://dojotoolkit.org/reference-guide/1.9/dijit/themes.html http://archive.dojotoolkit.org/nig ...
- 页面动态加入<script>标签并执行代码
在页面中动态追加html片段的时候,有时候动态添加的代码会含有<script>标签,比如用了一些模板引擎,或者你的代码有些复杂的时候.然而我们用DOM提供的innerHTML方式来添加代码 ...
- Comet实现的网页聊天程序
“上一篇”介绍了我在c/s程序中用了那些技术,如今只谈c/s不谈b/s那未免out了,势必要写一写b/s的程序与大家共勉. 回忆做技术这些年,06年每天盯着“天轰穿”的视频不亦乐乎,估计那是一代程序员 ...
- onCreateView中加载大位图
我的一个Fragment中,加载了一个1024*1024的图片,非常卡.解决办法 1. 将图片改为512*512 2. 异步加载. final SmartImageView mizige = (Sma ...
- 基于Task的异步模式的定义
返回该系列目录<基于Task的异步模式--全面介绍> 命名,参数和返回类型 在TAP(Task-based Asynchronous Pattern)中的异步操作的启动和完成是通过一个单独 ...