上周通过探讨SQL Server如何执行一个查询奠定了基础。我也在那里提到页是8kb的缓存。今天我们对页进行进一步集中探讨,从性能调优角度挖掘出更多的细节。

页是SQL Server的基础,在SQL Server里一切都与页有关。当我们想提高查询性能时,我们可以减少SQL Server指定查询所需页的读取。在第二个月当我们讨论索引时,我们发现其实索引的结构也是由页组成的。当你不知道页是什么的时候,你就不能对SQL Server进行调优和故障排除。

数据页结构

在SQL Server中页的大小始终是8kb的大小,页有不同的类型:数据页,索引页,系统页等等。今天我们对在SQL Server存储我们表数据的数据页进行更多细节的学习。一个数据页总是由三个部分组成:

  1. 页头(Page Header)
  2. 数据区(Payload)
  3. 行偏移数组(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 中数据存储的基本单位的更多相关文章

  1. 第2周 页_SQL Server 中数据存储的基本单位

    原文:第2周 页_SQL Server 中数据存储的基本单位 上周通过探讨SQL Server如何执行一个查询奠定了基础.我也在那里提到页是8kb的缓存.今天我们对页进行进一步集中探讨,从性能调优角度 ...

  2. 第3/24周 区_SQL Server中管理空间的基本单位

    哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Server内核运行机制有了很好的认识.今天我会讲下SQL Server中的区管理,因为这是个很重要的话题,我们会在第23周 ...

  3. 第3周 区_SQL Server中管理空间的基本单位

    原文:第3周 区_SQL Server中管理空间的基本单位 哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Server内核运行机制有了很好的认识.今天我会讲下SQL Se ...

  4. Android中数据存储(一)

    国庆没有给国家添堵,没有勾搭妹子,乖乖的写着自己的博客..... 本文将为大家介绍Android中数据存储的五种方式,数据存储可是非常重要的知识哦. 一,文件存储数据 ①在ROM存储数据 关于在ROM ...

  5. Android中数据存储(三)——SQLite数据库存储数据

    当一个应用程序在Android中安装后,我们在使用应用的过程中会产生很多的数据,应用都有自己的数据,那么我们应该如何存储数据呢? 数据存储方式 Android 的数据存储有5种方式: 1. Share ...

  6. Java基础知识强化之IO流笔记46:IO流练习之 把文本文件中数据存储到集合中的案例

    1.  把文本文件中数据存储到集合中      需求:从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合. 分析:      通过题目的意思我们可以知道如下的一些内容,      数据 ...

  7. android中数据存储

    android中数据存储     Android 中存储数据的方式有五种:SQLite数据库.文件存储.内容提供者.网络.SharedPreferences(Key----value)五种存储方式. ...

  8. Android中数据存储(四)——ContentProvider存储数据

    目录(?)[+]   当一个应用程序在Android中安装后,我们在使用应用的过程中会产生很多的数据,应用都有自己的数据,那么我们应该如何存储数据呢? 数据存储方式 Android 的数据存储有5种方 ...

  9. 第十七周翻译-SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志

    SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志 作者:Tony Davis,2012/01/27 翻译:赖慧芳 译文: 该系列   本文是Stairway系列的一部分:SQL ...

随机推荐

  1. apache httpclient CacheStorage的一个自定义实现

    import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io ...

  2. 我的ORM之九 -- 生成器

    我的ORM索引 数据库连接字符串格式 <add name="dbo" connectionString="" providerName="MyS ...

  3. 使用ABP时报错“UPDATE 语句与 FOREIGN KEY SAME TABLE 约束"FK_dbo.AbpUsers_dbo.AbpUsers_LastModifierUserId"冲突”的解决办法

    ABP理论学习总目录 一步一步使用ABP框架搭建正式项目系列教程 ABP之Module-Zero学习目录 本篇目录 问题 原因 解决办法 问题 问题的是在下面这种情况下出现的: 我在使用CodeFir ...

  4. Win10 UWP开发中的重复性静态UI绘制小技巧 1

    介绍 在Windows 10 UWP界面实现的过程中,有时会遇到一些重复性的.静态的界面设计.比如:画许多等距的线条,画一圈时钟型的刻度线,同特别的策略排布元素,等等. 读者可能觉得这些需求十分简单, ...

  5. TypeError: 'bases' is null or not an object。IE8 bug 腐朽的对象

    使用Webapp Builder时候发现,在IE8上很奇怪的一个现象:在ajax回调函数中引用一个闭包作用域链中的对象作为某一个Dijit的实例化参数时有问题:bases is null or not ...

  6. ng-template寄宿方式

    如果你是一个angular的开发者的话,对于ng-html2js你应该 很熟悉.对于angular的指令,我们经常需要定义模板( directive template/templateUrl),你可以 ...

  7. EF架构~二级域名中共享Session

    回到目录 对于一个有点规模的网站,都会有各个子网站,说是子网站,其实也都是独立的站点,一般通过二次域名来分开,如www.zzl.com,它可以有很多子网站,如image.zzl.com,file.zz ...

  8. 题目一:打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方。

  9. js,格式化long类型日期封装

    /** * 扩展date函数 * author:c3gen */ Date.prototype.format = function(format) { var o = { "M+" ...

  10. iOS $299刀企业证书申请的过程以及细节补充(二)

    上篇博客写的过程中,没有图,也没有相应的说明.这次再补充一些信息: 1.从 https://developer.apple.com/ios/enroll/dunsLookupForm.action 申 ...