第4/24周 页面限制8060 bytes
恭喜您!在你面前就只剩下几页了,然后你就可以完成第1个月的SQL Server性能调优培训了。今天我将讲下页的一些限制,还有为什么你会喜欢这些限制,同时也会讨厌这些限制。
正如你在第2周学到的,数据页始终是8kb 的大小,而且你只能在上面存储8060 bytes。你的记录大小指示你在一个页里可以存储多少记录。当你与像CHAR,INT,DATETIME等定长类型数据类型打交道时,你会发现SQL Server有记录长度不能超过8060 bytes长度(包含7 bytes 的内部行开销)的限制。
页面限制——好的一面
当你的表少于8列时,你需要(为每条记录)增加额外7 bytes 的内部行开销。对每增加的8列都要增加额外的1 byte, 例如,17列,你需要9 btyes的内部行开销(7+1+1)。如果你尝试创建更长的记录大小,SQL Server会在你执行CREATE TABLE语句时返回一个错误信息给你。来看看下面的表定义:
CREATE TABLE TooLargeTable1
(
Column1 CHAR(5000),
Column2 CHAR(3000),
Column3 CHAR(54)
)
GO
正如你所见,每条记录需要8061 bytes(5000+3000+54+7 bytes)。因此在这种情况下,当你尝试去创建这个表时,SQL Server会返回下列的错误信息。

当你创建超过8列的表时,你需要把SQL Server需要的8 bytes的行内部开销也算进去。
CREATE TABLE TooLargeTable2
(
Column1 CHAR(1000) NOT NULL, Column2 CHAR(1000) NOT NULL,
Column3 CHAR(1000) NOT NULL, Column4 CHAR(1000) NOT NULL,
Column5 CHAR(1000) NOT NULL, Column6 CHAR(1000) NOT NULL,
Column7 CHAR(1000) NOT NULL, Column8 CHAR(1000) NOT NULL,
Column9 CHAR(53) NOT NULL
)
GO
因此这里又是一个非法的表定义(8000+53+8 bytes),这里SQL Server会返回一个错误信息。

页面限制——坏的一面
在上一环节我已经向你展示了页面限制你喜欢的一面,因为当你在创建这样表的时候,SQL Server会返回你一个错误信息。但是页面限制也有你讨厌的一面,因为SQL Server会允许你创建这样的表,而且有时INSERT语句执行成功,有时却会失败……我们来看下。
这里我们面对的问题是与像VARCHAR等变长数据类型。当这些列不能存在它本身页时,SQL Server会把它们移动到在另外页面的行偏移位置。这个被称为 行溢出页(Row-Overflow page)。SQL Server会在原来的页面留下24 bytes长的指向行溢出页的指针。
在于其他列组合时的某些情况下,这个指针会溢出8060 bytes的限制。我们来看下下面的表定义:
CREATE TABLE TooLargeTable3
(
Column1 CHAR(5000),
Column2 CHAR(3000),
Column3 CHAR(30),
Column4 VARCHAR(3000)
)
GO
如你所见,这里我使用了VARCHAR(3000)的数据类型。你会看到SQL Server这里会给你一个警告信息。这个警告提示你可以创建这个表,但在执行INSERT/UPDATE语句时可能会失败……

下面在表里的插入语句会成功:
INSERT INTO TooLargeTable3 VALUES
(
REPLICATE('x', 5000),
REPLICATE('x', 3000),
REPLICATE('x', 30),
REPLICATE('x', 19)
)
GO
这里的记录大小是8056 bytes长(5000+3000+30+19+7 bytes)。在这个情况下,SQL Server会把第4列的数据保存在主数据页。但是想像下下面的INSERT语句:
INSERT INTO TooLargeTable3 VALUES
(
REPLICATE('x', 5000),
REPLICATE('x', 3000),
REPLICATE('x', 30),
REPLICATE('x', 3000)
)
GO
在刚才的INSERT语句,SQL Server会把第4列数据移到行溢出页(row-overflow page),因为这3000 bytes 不能在主数据页里放下。这也就意味着SQL Server会在这里留下一个指向不同页且24bytes 长的指针,在那个位置可以找到数据。但是我们的记录大小现在是8061 bytes长(5000+3000+30+24+7 bytes)。
Duang,你的记录长度超过8060 bytes,INSERT语句执行失败了!

这些就是坏的限制,因为他们在数据库操作的时候隐藏着,好的一面就是在你定义表架构的时候如上所示可见的。想想看是啥?
小结
在你设计你的表结构时,你要非常仔细的想下你的操作。在SQL Server里与页打交道时你会碰到很多这样的执行进去后才出现的限制。当然,在SQL Server给你错误信息时,你不允许创建这个表,基本上就天下太平了。
当当你收到警告时,基本上每个人会想不都不想下就忽略掉。这始终是个坏的操作,因为你已经看到了,你的INSERT可能在运行时失败,问题的发生你是可以预见的。我希望你现在已经明白这个性能调优培训是个很好内幕公开,并且为什么理解数据页的内部结构是多么重要!
在接下来的培训我会讲解SQL Server中堆表的更多细节,还有为什么它们有时是好的(设计),有时候却是不好的(设计) 。请继续关注,并且好好享受剩下的7天!
围观PPT:
第4/24周 页面限制8060 bytes的更多相关文章
- 第4周 页面限制8060 bytes
原文:第4周 页面限制8060 bytes 恭喜您!在你面前就只剩下几页了,然后你就可以完成第1个月的SQL Server性能调优培训了.今天我将讲下页的一些限制,还有为什么你会喜欢这些限制,同时也会 ...
- 第0/24周 SQL Server 性能调优培训引言
大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...
- 分享Kali Linux 2017年第24周镜像文件
分享Kali Linux 2017年第24周镜像文件 Kali Linux官方于6月11日发布2017年的第24周镜像.这次维持了11个镜像文件的规模.默认的Gnome桌面的4个镜像,E17.KD ...
- 第3/24周 区_SQL Server中管理空间的基本单位
哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Server内核运行机制有了很好的认识.今天我会讲下SQL Server中的区管理,因为这是个很重要的话题,我们会在第23周 ...
- 第1/24周 SQL Server 如何执行一个查询
大家好,欢迎来到第1周的SQL Server性能调优培训.在我们进入SQL Server性能调优里枯燥难懂的细节内容之前,我想通过讲解SQL Server如何执行一个查询来建立基础.这个部分非常重要, ...
- 第2/24周 页_SQL Server 中数据存储的基本单位
上周通过探讨SQL Server如何执行一个查询奠定了基础.我也在那里提到页是8kb的缓存.今天我们对页进行进一步集中探讨,从性能调优角度挖掘出更多的细节. 页是SQL Server的基础,在SQL ...
- 第18/24周 乐观并发控制(Optimistic Concurrency)
大家好,欢迎回到性能调优培训.上个星期我通过讨论悲观并发模式拉开了第5个月培训的序幕.今天我们继续,讨论下乐观并发模式(Optimistic Concurrency). 行版本(Row Version ...
- 第19/24周 锁升级(Lock Escalations)
大家好,欢迎回到性能调优培训.上2个星期我们已经讨论了SQLServer里的悲观和乐观锁.今天我想谈下SQL Server里对于锁的一个特殊现象:所谓的锁升级(Lock Escalations).在我 ...
- 第20/24周 死锁(Deadlocking)
大家好,欢迎回到性能调优培训.今天讨论SQL Server里的死锁(Deadlocking),第5个月的培训就结束了.当2个查询彼此等待,没有查询可以继续它的工作就会发生死锁.第一步我会概括介绍下SQ ...
随机推荐
- Rubinius 2.0 发布,Ruby 虚拟机
Rubinius 2.0 发布了,官方发行说明请看这里. Rubinius是一个运行Ruby程序的虚拟机,其带有Ruby的核心库. Rubinius的设计决定了其调试功能的强大,使得在运行时常规的Ru ...
- WebApi Post提交报错 调试无法进入对应action函数
调试发现有长内容或者是特殊字符就报错,确定是服务端验证的问题 需要 在配置文件 <system.web> 中添加<httpRuntime requestValidationMode ...
- 收录.NET跨平台及跨数据库的博文...
本帖,将持续收录.NET跨平台及跨数据库的博文... VS2012+EF6+Mysql配置心路历程: http://www.cnblogs.com/gameman/p/3773240.html ASP ...
- WebRTC实现网页版多人视频聊天室
因为产品中要加入网页中网络会议的功能,这几天都在倒腾 WebRTC,现在分享下工作成果. 话说 WebRTC Real Time Communication 简称 RTC,是谷歌若干年前收购的一项技术 ...
- C#更改文件访问权限所有者(适用于各个Windows版本)
前面也提到了,前段时间在做Online Judge系统,在正式上线前有几个比较老的版本,其中第一个版本使用ACL来控制权限以确保安全(但是这个版本完全建立在IIS上,所以这样做是没效果的),遇到了一些 ...
- 《C#图解教程》读书笔记之六:接口和转换
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.接口那点事儿 (1)什么是接口? 一组函数成员而未实现的引用类型.只有类和结构能实现接口. (2)从ICom ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(七):解决用户上下文(Session)问题
从这篇文章中我们已经了解了微信公众平台消息传递的方式,这种方式有一个先天的缺陷:不同用户的请求都来自同一个微信服务器,这使得常规的Session无法使用(始终面对同一个请求对象,况且还有对方服务器Co ...
- Spring Trasnaction管理(1)- 线程间事务隔离
问题导读 Spring中事务是如何实现的 Spring中各个线程间是如何进行连接.事务隔离的 Spring事务配置 Spring的事务管理应该是日常开发中总会碰到的,但是Spring具体是怎么实现线程 ...
- javaweb学习总结—Apache的DBUtils框架学习
注明: 本文转载自http://www.cnblogs.com/xdp-gacl/p/4007225.html 一.commons-dbutils简介 commons-dbutils 是 Apache ...
- ECMAScript5中数组的方法
1.forEach()方法 遍历数组,为每个数组元素调用指定函数,三个参数分别为:数组元素 item.元素索引 index.数组本身 arr,无返回值 例: 2.map()方法 调用数组的每个元素传递 ...