无论是哪一个数据库,如果要对数据库的性能进行优化,那么必须要了解数据库内部的存储结构。否则的话,很多数据库的优化工作无法展开。对于对于数据库管理员来说,虽然学习数据库的内存存储结构比较单调,但是却是我们必须攻下的一个堡垒。在SQLServer数据库中,数据页是其存储的最基本单位。系统无论是在保存数据还是在读取数据的时候,都是以页为单位来进行操作的。

  

  一、数据页的基本组成。

  如上图所示,是SQLServer数据库中页的主要组成部分。从这个图中可以看出,一个数据页基本上包括三部分内容,分别为标头、数据行和行偏移量。其中数据行存储的是数据本身,其他的标头与偏移量都是一些辅助的内容。对于这个数据页来说,笔者认为数据库管理员必须要了解如下的内容。

  一是要了解数据页的大小。在SQLServer数据库中数据页的大小基本上是固定的,即每个数据页的大小都为8KB,8192个字节。其中每页开头都有一个标头,其占据了96个字节,用于存储有关页的信息。如这个页被分配到页码、页的类型、页的可用空间以及拥有这个页的对象的分配单元ID等等信息。不过值得庆幸的是,这些内容数据库都会自动管理与更新,不需要数据库管理员担心。数据库管理员只需要知道的是,这个数据页中最多可以用来保存数据的空间。每个页的大小是8192个字节,扣除掉一些必要的开销(如标头信息或者偏移量所占用的空间),一般其可以用来实际存储数据的空间只有8000字节左右。牢记这个数字,对于后续数据库性能的优化具有很大的作用。详细的内容笔者在后续行溢出的部分会进行说明。

  二是需要注意行的放置顺序。在每个数据页上,数据行紧接着标头按顺序放置。在页的末尾有一张行偏移表。对于页中的每一行,每个行偏移表都包含有一个条目。即如果业中的数据行达到100条的话,则在这个行偏移表中就对英100个条目。每个条目记录中记录对应行的第一个字节与页首的距离。如第二个跳就记录着第二个数据行的行首字母到数据页页首的位置。由于每个数据行的大小都是不同的,为此这个行偏移表中记录的内容也是没有规律的。这里需要注意的是,行偏移表中的条目顺序与页中行的顺序是相反的。这主要是为了更方便数据库定位数据行。

  二、大数据类型与行。

  根据SQLServer数据库定义的规则,行是不能够跨页的。如上图所示,如果一个字段的数据值非常大,其超过8000字节。此时一个页已经不能够容纳这个数据。此时数据库会如何处理呢?虽然说在SQLServer数据库中,行是不能够跨页的。但是可以将行分成两部分,分别存储在不同的行中。所以说,对于大数据类型来说,是不受到这个页大小(或者说行大小)的限制的。根据上面的分析可以看出,一个数据页其最大可以用的存储空间在8KB。如果扣掉一些必要的开销,其只有8000字节左右。当某条记录的所有列(包括固定长度的列与可变长度的列其大小超过这个限制的时候,数据库就会将其进行分行处理,分别存储在两个不同的页中。当某张表格中列的总大小超过限制的8KB(实际上还还不到一点)字节时,数据库系统会从最大长度的列开始动态的将一个或多个可变长度列移动到另外一个页中。简单的说,就是将某个列超过的部分单独存放在另一个页中。并且同时还会存储一些指针之类的信息,以便在不同页的记录中建立关联。这种现象在SQLServer数据库中给其取了一个名字,叫做行溢出。

  三、行溢出对于数据库性能的不利影响。

  掌握了上面关于数据页的基本工作原理后,数据库管理员需要重点理解行溢出对于数据库性能的不利影响。即需要了解,当所有列(包括固定长度的列与可变长度的列)的累积长度超过一个数据页(或者一个数据行)的最大承受限度时,会将列的内容分行来进行存放。数据库如此处理,对数据库的性能会有不利的影响吗?如果有的话,该如何避免?

  一般来说,每行的记录超过页的最大容量时,肯定会对数据库的性能造成不利的影响。这是毋庸置疑的。因为当超过这个容量时,数据库系统就需要对这个数据行进行分页处理。而分页处理需要数据库额外的开销。如在分页保存时,需要给数据库添加额外的指针;在查询数据的时候,由于分页情况的存在,为了读取一条完整的记录,数据库系统可能不得不读取多页的内容;当进行更新操作,将某个字段的内容变短,导致整行的内容在页的最大范围之内,则相关的记录会被保存在同一个行中。这些操作都需要数据库额外的开销。当在同一个时间处理这些作业多了,那么积累起来,对数据库性能的影响就会很显著。同理,此时如果对相关的记录进行排序、统计等操作,由于涉及到多个页,会延长这些作业的执行时间,即降低数据库的性能。

其次需要注意的是对一些变长字段的限制。在SQLServre数据库中,也含有varchar等变长的数据类型。在SQLServer数据库中对此有最大长度的限制。一般情况下,其最大长度不能够超过不能够超过8000字节的限制。不过他们的总宽度可以超过这个8KB的限制。如果单列的数据长度超过这个限制,那么就不能够使用普通的数据类型。如对于那些用来保存图片或者多媒体的数据,必须要使用大对象数据类型。因为只有这些大对象数据类型不受这个长度的限制。数据库对对于这些大型数据库类型对象有特殊的处理方法。

  四、数据库设计时的注意事项。

  在数据库运行时,如果存在比较多的行溢出现象,会在很大程度上影响数据库的性能。所以在数据库设计时,需要考虑到这种情况。一般的数据类型不会造成行溢出的情况。只有一些varchar nvarchar或者CLR用户自定义类型的列,比较容易造成这个行溢出现象。所以在设计数据库时,数据库管理员应该根据用户提供的样板数据分析可能发生行溢出现象的百分比,以及评估会发生溢出现象的频率。如果溢出现象发生的百分比或者频率比较高的话,那么数据库管理员就需要考虑对表格进行规范化处理,以提高数据库的性能,减少溢出现象对于数据库的不利影响。

  一般来说,有两种方法可以显著的降低这个行溢出现象对数据库性能的影响。一是假设列定义了varchar或者用户自定义数据类型等数据类型的时候,如果其长度比较长,很有可能引起行溢出现象的话,那么就干脆使用大对象数据类型。对于大对象数据类型SQLServer数据库会采取特殊的管理方法,会讲这个数据与普通数据分开来管理。所以可以在很大程度上降低行溢出现象对数据库性能的影响。不过需要注意的是,管理这些大对象数据类型,数据库本身就需要花费更多的精力与资源。所以采用这种方式带来的收益,与行溢出现象带来的损失就会有一个轻重之分的问题。数据库管理员要评估由此带来的收益能够弥补行溢出对象带来的损失。如果可以弥补的话,那么可以采用这个方案。如果不可以的话,那就得不偿失了。故笔者并不是很推荐使用这种方法。笔者现在采用的是下面要介绍的这种方式。

  第二种方法执行起来比较简单,具有比较强的可执行性。即如果某个表格中有varchar或则用户自定义的数据类型,而且其最大长度也比较长,很容易造成行溢出现象。此时最好将这些列与表中的其他列分开来存放。即将他们放在两张不同的表中。然后再通过join语句来进行连接。由于数据页对单个列的最大长度有限制,所以如此处理的话,就不怎么会发生行溢出的现象。此时如果需要查询完整的记录,也需要访问多个页。但是在实际工作中,往往不需要访问全部的信息。如在更新或者统计操作时,不需要更新varchar数据类型的字段,那么数据库的效率就会有很大的提升。即使需要访问完整的记录,需要访问多个页。但是采取join操作也要比行溢出操作性能来的好。如在更新数据时将varchar的列缩短了,此时由于在两个不同的表中,也不会出现合并行的问题。所以可以在很大程度上节省数据库的开销。显然,这种分表处理的方式更加简单,很容易操作。所以笔者强烈建议采用这种方式来避免行溢出对SQLServer数据库造成的不利影响。

SQLServer中的页如何影响数据库性能 (转)的更多相关文章

  1. mysql中影响数据库性能的因素讲解

    mysql中影响数据库性能的因素讲解 在本篇文章中我们给大家讲述了mysql中影响性能的因素以及相关知识点内容,有兴趣的朋友参考下 关于数据库性能的故事 面试时多多少少会讲到数据库上的事情,“你对数据 ...

  2. 转载:SqlServer数据库性能优化详解

    本文转载自:http://blog.csdn.net/andylaudotnet/article/details/1763573 性能调节的目的是通过将网络流通.磁盘 I/O 和 CPU 时间减到最小 ...

  3. SqlServer数据库性能优化详解

    数据库性能优化详解 性能调节的目的是通过将网络流通.磁盘 I/O 和 CPU 时间减到最小,使每个查询的响应时间最短并最大限度地提高整个数据库服务器的吞吐量.为达到此目的,需要了解应用程序的需求和数据 ...

  4. (转)Db2 数据库性能优化中,十个共性问题及难点的处理经验

    (转)https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid=2650629396&idx=1&sn=3ec17927b3d ...

  5. SQLSERVER 数据库性能的的基本

    SQLSERVER 数据库性能的基本 很久没有写文章了,在系统正式上线之前,DBA一般都要测试一下服务器的性能 比如你有很多的服务器,有些做web服务器,有些做缓存服务器,有些做文件服务器,有些做数据 ...

  6. Oracle中HWM与数据库性能的探讨

    Oracle中HWM与数据库性能的探讨 一.什么是高水位 HWM(high water mark),高水标记,这个概念在segment的存储内容中是比较重要的.简单来说,HWM就是一个segment中 ...

  7. SQLServer中数据库文件的存放方式,文件和文件组

    我们公司近一年来做了一个CRM系统. 遇到一个问题就是:在插入交流记录的时候速度特别慢.(交流记录数据量大) 后来我们经理采用文件组的方法,将客户交流记录这张表提出来就快很多了 这里有一篇关于文件组的 ...

  8. SQLSERVER 数据库性能的的基本 MVC + EF + Bootstrap 2 权限管理

    SQLSERVER 数据库性能的基本 很久没有写文章了,在系统正式上线之前,DBA一般都要测试一下服务器的性能 比如你有很多的服务器,有些做web服务器,有些做缓存服务器,有些做文件服务器,有些做数据 ...

  9. 使用有序GUID:提升其在各数据库中作为主键时的性能

    原文出处:https://www.codeproject.com/articles/388157/guids-as-fast-primary-keys-under-multiple-database  ...

随机推荐

  1. ModelState.IsValid总为false原因

    总结在开发中遇到的一个问题 ModelState.IsValid 一直是false 且在局部变量中,没有发现有问题啊,Model非常正常有木有,可是为什么 ModelState.IsValid 总是f ...

  2. C#: 向Word插入排版精良的Text Box

    Text Box(文本框)是Word排版的工具之一.在Word文档正文的任何地方插入文本框,可添加补充信息,放在合适的位置,也不会影响正文的连续性.我们可以设置文本框的大小,线型,内部边距,背景填充等 ...

  3. 浅谈2D游戏设计模式2- WZ文件详解(UI.WZ)之MapLogin.img(1)

    玩过冒险岛的人都知道有一个WZ文件,那么这个WZ文件的内部是怎么样的呢,今天我就带大家一探究竟. 说实在的,我这是第一次接触WZ文件,但是却让我很震撼,为什么很震撼,因为这个居然是用VS2010写的! ...

  4. WebApp上滑加载数据...

    $(window).bind("scroll", function () { if ($(document).scrollTop() + $(window).height() &g ...

  5. Linux中读写权限

    learn the auth of Linux.   Generally, r-x w: write , modify and delete  -2 r: read   -4 x: execute   ...

  6. mybatis入门基础(九)----逆向工程

    一.什么是逆向工程 mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml.po. ...

  7. CSS魔法堂:重拾Border之——图片作边框

    前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-t ...

  8. 重构sql server的sys.sp_helptext存储

    本文目录列表: 1.sys.sp_helptext存储的功能和效果 2.重构sys.sp_helptext存储(命名为dbo.usp_helptext)提供直观的效果 3.sys.sp_helptex ...

  9. FPGA的引脚VCCINT 、VCCIO VCCA

    首先是看到FPGA在配置的时候有三种不同的电VCCINT .VCCIO VCCA,于是就查了下有什么不同: FPGA一般会有许多引脚,那它们都有什么用呢? VCCINT为施加于 FPGA 内核逻辑的电 ...

  10. 关系数据库SQL之基本数据查询:子查询、分组查询、模糊查询

    前言 上一篇关系数据库常用SQL语句语法大全主要是关系型数据库大体结构,本文细说一下关系型数据库查询的SQL语法. 语法回顾 SELECT [ALL|DISTINCT] <目标列表达式>[ ...