sql server的存储机制

区段: 是用来为表和索引 分配空间的基本存储单元. 由 8个连续的页面构成,大小为64kb.

区段的注意事项:

  • 一旦区段已满,那么下一记录 将要占据的空间不是记录的大小,而是整个区段的大小.
  • 通过预先分配空间,sql server节省了为每个记录分配新空间的时间

页: 页是在到达实际数据行 之前所能达到的最后一个存储级别.尽管每个区段中的页数是固定的,但是每一页中的行数 不是固定的--这完全取决于行的大小,而行的大小 可以变化的. 可以把 页 看作是 表行和索引行的容器.通常不允许行跨页.就是行的大小 最大为8kb.

下面介绍两种不同的页类型:

  • 数据页: 就是表中的实际数据
  • 索引页:它们既包括 非聚集索引的非叶级页和页级页. 又包括聚集索引的非叶级页

行:

最大可达8kb,除了 8060字符的限制外,还有最大1024标准列(非稀疏列)的限制.

稀疏列:

使用稀疏列,可以讲单个表中允许的列的总数 提高到 30000.

在内部,标记为稀疏的列 的数据 嵌在单个列中--可以打破之前的1024列的限制,而不用做较大的体制结构的更改.

理解索引

索引就是能够快速访问数据的方法.

索引中的存储顺序取决于 为数据建立的排列规则信息.可以再数据库或者列级设置排列规则.

平衡树:

平衡树或者 B-Tree 仅是提供一种以一致且相对低成本的方式查找特定信息的方法.

页拆分简介:

每次遇到树中的分支时,因为每一边都有约有一半的数据,所以B-树 是平衡的.

通过将数据添加到树上,节点最终将变满,并且需要拆分,因为sql  server中,一个节点相当于一个页--所以这杯称为页拆分.

也拆分做的操作:

  • 创建新页
  • 将行从现有的页移动到新页
  • 将新行添加到其中一页上
  • 在父节点中添加另一个记录项

但是系统开销不仅仅是这些.因为在进行树的排列,就可能导致级联操作.创建新页时(因为拆分的缘故),需要在父节点中

建立另一个记录项,在父节点中的这个记录项在该 级别也可能导致页拆分,而且整个过程会重新开始.

如果根节点拆分,那么实际最终会创建两个额外的页.由于只能有一个根节点,所以之前作为根节点的页被拆分成两个页,而且成为树的新

中间级别.然后创建全新的根节点.并且将有两个记录项.

显然,拆分页对系统性能产生非常负面的影响,其表现是 在服务器上 的处理会暂停几秒.

sql server 中 访问数据的方式:

广义上讲,sql server检索数据的方式 只有两种.

  • 使用表扫描
  • 使用索引扫描

使用表扫描:

表扫描是个很直观的过程.sql server 从表的物理起点 开始,浏览表中的每一行,当发现和查询条件匹配的行时,

就在结果集中包含它们.

使用索引:

在查询优化过程中,优化器查看所有可用的索引结构,并选择最好的一个(这主要基于在连接和where子句中指定的信息,以及sql server

在索引结构中保存的统计信息). 一旦选择的索引,sql server 将在树结构中导航至与条件匹配的数据位置,并且只提取它所需要的记录.

区别在于,因为数据时排序的,所以查询引擎知道 它何时到达正在查找的当前范围的下界,然后他可以结束查询,或者根据需要移至下一数据范围.

索引类型和索引导航

  • 聚集索引
  • 非聚集索引( 有包括两个: 堆上的非聚集索引,  聚集表上的非聚集索引)

物理数据的 存储方式 在 聚集索引和非聚集索引中时不同的. 而  sql server 遍历平衡树已到达末端数据的方式 在所有三种

索引类型中,也是不同的.

索引在 聚集表(如果表有聚集索引)或者堆(用于没有聚集索引的表)上创建.

聚集表: 是 在其上具有聚集索引的任意表.

它们对于表而言意味着 以 指定  物理顺序 存储数据.通过使用聚集键唯一的标示独立的行---聚集键 即 定义聚集索引的列.

堆: 在其上没有聚集索引的任意表. 在这种情况下,基于 行的区段,页,以及行偏移量的组合创建唯一的标示符,或者成为RID,

如果没有可用的聚集键,那么RID是唯一必要的内容.

聚集索引:

聚集索引对于 任意给定的表而言都是唯一的.

聚集索引的叶级 是 实际的数据.

数据重新排序,按照和索引排序条件声明的相同物理顺序存储.这意味着,一旦到达索引的叶级,就到达了 数据.

任何新纪录都根据其正确的物理顺序插入到群集索引中.创建新页的方式也随插入记录的位置而变化.

当发生页面拆分时,数据自动的四处移动一 保持平衡. 数据的前半部分保留在旧页上,而数据的剩余部分添加到新页.-这样就形成的了对半分,

使得树 保持平衡.

-----------------------------------

堆上的非聚集索引

这个索引 的页级不是数据,而是指向数据的一个指针。 该指针 以RID的形式出现,这种RID由 索引指向的特性行的区段,页以及

偏移量组成。

注意: 堆上的非聚集索引 和聚集索引一样,通常任何已通过读取一次的页 将 仍然 在内存中缓存,而且同样将非常快速的呗检索.

聚集表上的非聚集索引

这种索引和堆上的非聚集索引 一样,索引的非叶级节点的工作与使用 聚集索引时相比几乎一样,区别在于 叶级.

在聚集表上的非聚集索引 ,在 叶级 找到的是 聚集键,也就说,找到足够的信息 继续并利用聚集索引.

何时何地使用何种索引

索引,特别是 非聚集索引,主要在 索引中 有相当高级别的选择性的情况下是有益的.

所谓的选择性就是 列中唯一值的百分比.   唯一值百分比越高,选择性越高.从而索引的用处就越大.

索引的成本:

虽然索引能在查询时 提高效率,但是在修改数据时,实际上花费很高.每次对数据进行修改时,任何与数据有关的索引也将需要更新,

对于每个创建的索引,意味着 创建了 一组 必须更新的条目.

那么为什么是一组条目呢,因为 平衡树有多个级别,每次对叶级进行修改时,就可能产生页拆分,而且也必须修改一个或者多个 非叶级页.

维护索引

就索引维护而言,需要处理一下两个问题:

  • 页拆分
  • 碎片

这两个问题 都和  液密度  有关,虽然两者在表现形式上有本质区别,但是故障排除工具是一样的.

碎片:

当 数据库增长,页拆分,然后删除数据时,都会产生碎片.

虽然从增长的角度看,平衡树机制 在保持平衡方面做的不错,但是在删除数据时,将没有太多作用.最终可能出现这样一种情况:

其中在这一页上有一个记录,而在那一页有几个记录--意味着页没有被填满,

  1. 关于碎片 首先会想到的就是 ----浪费空间.前面 说过,sql server 每次分配一个区段的空间,如果 一个页 只有一条记录,仍然会分配一个区段.
  2. 散步在各处的记录会造成 数据检索时  的额外开销.

虽然如此,碎片也有好的一面,—OLTP系统就喜欢碎片,因为 也拆分.没有许多数据的页 在插入数据时,几乎不用担心也拆分.

所以:大量的碎片 意味着 较差的读取性能,但是也意味着  极好的插入性能.

确定碎片和也拆分的可能性:

sql server 提供了一个元数据 函数  sys.dm_db_index_physical_stats ,有助于确定数据库中的页和区段有多满.

那么次函数的参数如下:

参数说明:数据库id,对象id,索引类别id (1聚集索引  0堆  2 非聚集索引)

a表结果:

一个主键,自带一个clustered index

下面看sql :

declare @db_id smallint
declare @ob_id int
set @db_id=DB_ID('test')
set @ob_id=object_id('a')
select * from sys.dm_db_index_physical_stats(@db_id,@ob_id,null,null,null)

.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) } .csharpcode pre { margin: 0 } .csharpcode .rem { color: rgba(0, 128, 0, 1) } .csharpcode .kwrd { color: rgba(0, 0, 255, 1) } .csharpcode .str { color: rgba(0, 96, 128, 1) } .csharpcode .op { color: rgba(0, 0, 192, 1) } .csharpcode .preproc { color: rgba(204, 102, 51, 1) } .csharpcode .asp { background-color: rgba(255, 255, 0, 1) } .csharpcode .html { color: rgba(128, 0, 0, 1) } .csharpcode .attr { color: rgba(255, 0, 0, 1) } .csharpcode .alt { background-color: rgba(244, 244, 244, 1); width: 100%; margin: 0 } .csharpcode .lnum { color: rgba(96, 96, 96, 1) }

下面看一下 返回的部分数据:


 
表中明确给出, 索引类型, 平均碎片百分比, 和 索引深度.
 
下面取消 a表的id主键,再次查看:结果如下:

 

.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) } .csharpcode pre { margin: 0 } .csharpcode .rem { color: rgba(0, 128, 0, 1) } .csharpcode .kwrd { color: rgba(0, 0, 255, 1) } .csharpcode .str { color: rgba(0, 96, 128, 1) } .csharpcode .op { color: rgba(0, 0, 192, 1) } .csharpcode .preproc { color: rgba(204, 102, 51, 1) } .csharpcode .asp { background-color: rgba(255, 255, 0, 1) } .csharpcode .html { color: rgba(128, 0, 0, 1) } .csharpcode .attr { color: rgba(255, 0, 0, 1) } .csharpcode .alt { background-color: rgba(244, 244, 244, 1); width: 100%; margin: 0 } .csharpcode .lnum { color: rgba(96, 96, 96, 1) }

注意 索引类型:  由 clustered index 变成了 heap  ,说明了 没有聚集索引的表 称为 堆表.

查看到相关信息后,那么就像去改变索引,

使用 fillfactor 填充因子 来改变页面的密度:

alter index PK_a(键名) on a(表名) rebuild with (fillfactor = 90) 填充因子越大,空闲空间就越大.

下面提供两种 查看 表中索引的  函数:

  1. select * from sys.dm_db_index_operational_stats(db_id('test'),object_id('a'),null,null)
    
  2. declare @db_id smallint
    declare @ob_id int
    set @db_id=DB_ID('test')
    set @ob_id=object_id('a')
    select * from sys.dm_db_index_physical_stats(@db_id,@ob_id,null,null,null)
    

sql server 2008学习8 sql server存储和索引结构相关推荐

  1. sql server 2008学习5 sql基础

    查看数据库的信息: INFORMATION_SCHEMA.CHECK_CONSTRAINTS INFORMATION_SCHEMA.COLUMN_DOMAIN_USAGE INFORMATION_SC ...

  2. SQL Server 2008 Datetime Cast 成 Date 类型可以使用索引(转载)

    很久没写blog,不是懒,实在是最近我这的访问速度不好,用firefox经常上传不了图片 ....... 今天无意发现了SQL Server 2008 Datetime Cast 成 Date 类型可 ...

  3. 微软sql服务器2008 R2,Microsoft SQL server 2008 R2 安装步骤

    下载Microsoft SQL Server 2008 R2,打开安装文件夹,以管理员身份运行setup.exe.(自行找资源,实在没有的私我.因需要只写了2008版本的安装步骤,2012等新版本的安 ...

  4. Windows Server 2008之旅??Windows Server Backup功能_闲云野鹤?精神家园_百度空间

    为什么80%的码农都做不了架构师?>>>    Windows Server 2008之旅??Windows Server Backup功能 2008-08-17 10:43 备份无 ...

  5. 一种非信任证书自动更新方法(可用于Windows Vista, Windows Server 2008,Windows 7,Windows Server 2008 R2)

    一种非信任证书自动更新方法(可用于Windows Vista, Windows Server 2008,Windows 7,Windows Server 2008 R2) 介绍 一种针对Windows ...

  6. 7代cpu能装虚拟xp系统吗_Windows server 2008 R2和Windows server 2003系统有什么区别?

    作为专业的服务器供应商,遇到了很多客户都会问Windows 2008和2003系统有什么区别?为此,今天和大家分享一下08和03的不同之处 1.2003相对于2008系统版本比较低,导致附带的功能组件 ...

  7. SQL Server 2008/2012中SQL应用系列及BI学习笔记系列--目录索引

    SQL Server 2008中的一些特性总结及BI学习笔记系列,欢迎与邀月交流. 3w@live.cn  ◆0.SQL应用系列 1.SQL Server 2008中SQL增强之一:Values新用途 ...

  8. sql server 2008学习3 表组织和索引组织

    表组织 表包含在一个或多个分区中,每个分区在一个堆或一个聚集索引结构包含数据行.堆页或聚集索引页在一个或多个分配单元中进行管理,具体的分配单元数取决于数据行中的列类型. 聚集表.堆和索引 SQL Se ...

  9. sql server 2008学习1–系统数据库

    master数据库 数据库记录 SQL Server 系统的所有系统级信息.这包括实例范围的元数据(例如登录帐户).端点.链接服务器和系统配置设置.此外,master 数据库还记录了所有其他数据库的存 ...

最新文章

  1. 微软发起Java on Azure调查,呼吁Java社区积极参与
  2. python在读写文件之前需要创建文件对象-python基础教程:文件读写
  3. opencv图片全景拼接详解
  4. 开源播放器 ijkplayer (一) :使用Ijkplayer播放直播视频
  5. apue对java_[apue] 一个快速确定新系统上各类限制值的工具
  6. python二维散点分布图_深入理解皮尔逊相关系数amp;python代码
  7. 【LeetCode】剑指 Offer 15. 二进制中1的个数
  8. 速修复!开源企业自动化软件 Apache OFBiz 出现严重的 RCE 漏洞
  9. extjs office java_Extjs使用(最最基础)
  10. MySQL-ProxySQL中间件Admin Schemas介绍
  11. phpstorm ctrl 鼠标左键 无效_击败无聊的办公室重复操作,用 Python 控制鼠标和键盘...
  12. matlab数据导入 spss,【excel数据导入系统】excel数据导入_excel数据导入spss-系统城...
  13. 史上最强单片机科普,看完给跪了!
  14. 黑马Python笔记1
  15. android studio设置SVN忽略
  16. 使用moment.js加减日期时间
  17. mysql及格率70以上_数据库实例(统计最高分学生信息,不及格率等等)
  18. bugku之密码ok解题思路
  19. 如何制作一首歌的歌词 LRC 歌词制作和绑定
  20. Redis中setex与setnx的区别?

热门文章

  1. C++检查图是否为二部图的算法(附完整源码)
  2. QT的QGraphicsLinearLayout类的使用
  3. QML基础类型之real
  4. C/C++人机猜拳游戏
  5. java 很垃圾_JAVA吧真的很垃圾!!!
  6. 「C++」C++ Primer Plus 笔记:第三章 处理数据
  7. mule 基于wsdl调用cxf web service
  8. MyEclipse:Available memory is low解决办法
  9. Android-电话录音服务
  10. VirtualBox通过命令方式批量创建并配置虚拟机