Sql Server专题一:索引(上)

写在前面的废话索引问题已经是老生常谈的问题,虽然被经常说起,但作为我来说,至今没有用过索引(很可怕吧),我作为MS-BI实施工程师居然没用过索引,说话自然没底气。之前对索引的了解停留在“知道”的地步上,随着时间的流逝感觉不真正将索引应用起来简直是渣渣!废话到此为止,开始索引专题,为了彻彻底底(我不是DBA,能将索引理解达到熟练使用即可,所以并不彻底)搞懂索引,从数据页学习吧!本篇主要来源MS的联机文档!

  •      页和区系统结构

    页:SQL Server中数据存储的基本单元便是页。为数据库中的数据文件分配的磁盘空间可以从逻辑上划分成页(从0到N连续编号)。磁盘的I/O操作在页级别执行。也就是说SQLSERVER读取或写入所有数据页。

    怎样理解呢?作为存储单位,这里给个不恰当的比喻:一个养猪场,有很多猪圈,每个猪圈看作存储数据的页。作为饲养员的我,假设我对养猪场的猪进行买卖,我的操作对象是猪没错,但是,其实我们也是在猪圈的基础上进行买卖,首先,我会对猪圈进行编号,然后,去买卖不同编号里的猪。所以可以理解为:我把猪(数据)养在不同编号(磁盘空间从逻辑上划分成0到N连续编号)的猪圈(页)里面,我买卖(I/O操作)这些猪,都是来自各个猪圈的。

    页的大小为8K。每页的开头是96字节的标头,用于存储有关页的信息。此信息包括:页码,页类型,页的可用空间以及拥有该页的对象的分配单元ID。

    这句话好理解:每个猪圈能养几头猪(8k),每个猪圈有个猪圈牌,猪圈牌上写点啥呢?当然要写:几号猪圈,是公猪圈、母猪圈、还是猪崽圈,已经养了几头猪以及这个猪圈的负责人联系方式。

    下面列出MSSQL中数据页的种类(公猪圈、母猪圈、还是猪崽圈):


    页类型


    内容


    Data


    当 text in row 设置为 ON 时,包含除 text、  ntext、image、nvarchar(max)、varchar(max)、varbinary(max) 和 xml 数据之外的所有数据的数据行。


    Index


    索引条目。


    Text/Image


    大型对象数据类型:

    ·          text、 ntext、image、nvarchar(max)、varchar(max)、varbinary(max) 和 xml 数据。

    数据行超过 8 KB 时为可变长度数据类型列:

    ·          varchar、nvarchar、varbinary 和 sql_variant


    Global  Allocation Map、Shared Global Allocation Map


    有关区是否分配的信息。


    Page  Free Space


    有关页分配和页的可用空间的信息。


    Index  Allocation Map


    有关每个分配单元中表或索引所使用的区的信息。


    Bulk  Changed Map


    有关每个分配单元中自最后一条 BACKUP LOG 语句之后的大容量操作所修改的区的信息。


    Differential  Changed Map


    有关每个分配单元中自最后一条 BACKUP  DATABASE 语句之后更改的区的信息。

    在下来看看猪圈的样子吧:

    上面是一个页的示例图:注意,在数据页上,数据行紧接着标头按顺序放置,页的末尾是行偏移表,对于页中的每一行,每个行偏移表都包含一个条目,每个条目记录对应行的第一个字节与页首的距离(行偏移量之前一直不理解,现在我理解的就是,假设每头猪不会动的按照行排列在猪圈中,每头猪距离猪圈门口的距离就是偏移量,当然这个距离-行偏移量也像猪圈牌一样是记录在另一个“牌子”上的,只不过它不按照123的顺序记录,是倒叙的)。行偏移表中的条目的顺序与页中行的顺序相反(至于为什么是相反的顺序,我猜是从数据结构等等高深的角度考虑吧,暂且理解为写这个行偏移量猪牌的人,站在猪圈尾端,先看到了最后一头猪,所以倒着记录了,没准MS就是这么设计的,哈哈!)。

至此,MS的这个猪圈看似可以养猪了,但是,一种极端的情况呢?这头猪,变异了,猪腿超级大,一个猪圈养不下怎么办!注意力,注意了,看MS怎办了:行不能跨页,但是行的部分可以移出行所在的页,因此行实际可能非常大(看到一头没有腿的小猪,不要嫌弃它小,没准的腿比大象的还粗!)。对了,将猪腿切下来,单独放……下面是MS的具体做法:页的单个行中的最大数据量和开销是8060字节(8K);但是不包括用Text/Image页类型存储的数据(为什么不包括这些类型的页呢?原因很简单,有些猪圈是经过特别设计的专门存放超大猪的,是整个猪,不是一个猪腿。),包括varchar ,nvarchar,varbinary或sql_variant列的表不受此限制的约束。当表中的所有固定列和可变列的行的总大小超过限制的8k时,SQL SERVER将从最大的列开始动态将一个或者多个可变长度列移动到 ROW_OVERFLOW_DATA分配单元中的页。(自述:将表中列移动到其他页)。每当插入或更新操作将行的总大小增大到超过限制的 8,060 字节时,将会执行此操作。将列移动到 ROW_OVERFLOW_DATA 分配单元中的页后,将在 IN_ROW_DATA 分配单元中的原始页上维护 24 字节的指针。如果后续操作减小了行的大小,SQL Server 会动态将列移回到原始数据页。

区:区是管理空间的基本单位。是八个物理上连续的页集合,用来有效的管理页,所有的页都存在区中。为了使空间分配更有效,SQL Server 不会将所有区分配给包含少量数据的表。这个好理解:8个猪圈就是一个大猪圈。一两头猪,MS是不会把它放在一个大猪圈中的。SQL Server 有两种类型的区:统一区,由单个对象所有。区中的所有8页只能由所属对象使用。混合区,最多可由八个对象共享。区中八页的每页可由不同的对象所有。统一区相当于猪圈的猪来自同一家农户。混合区相当于猪来自不同农户。

 

  • 管理区分配和可用空间

    大多数分配信息不是链在一起的。这就简化了对分配信息的维护。可以快速执行每个页的分配或释放。这将减少需要分配页或释放页的并发任务之间的争用。

管理区的分配  SQL SERVER使用两种类型的分配映射表来记录区的分配(下面的就好理解了一个养猪场怎么管好大量的猪圈呢,肯定想法设法记录有用信息来合理使用猪圈):

全局分配映射表(GAM):GAM 页记录已分配的区。每个 GAM 包含 64,000 个区,相当于近 4 GB的数据。GAM 用一个位来表示所涵盖区间内的每个区的状态。如果位为 1,则区可用;如果位为 0,则区已分配。

共享全局分配映射表 (SGAM):SGAM 页记录当前用作混合区且至少有一个未使用的页的区。每个 SGAM 包含 64,000 个区,相当于近 4 GB 的数据。SGAM 用一个位来表示所涵盖区间内的每个区的状态。如果位为 1,则区正用作混合区且有可用页。如果为 0,则区未用作混合区,或者虽然用作混合区但其所有页均在使用中。

跟踪可用空间 页可用空间 (PFS) 页记录每页的分配状态,是否已分配单个页以及每页的可用空间量。PFS 对每页都有一个字节,记录该页是否已分配。如果已分配,则记录该页是为空、已满 1% 到 50%、已满 51% 到 80%、已满 81% 到 95% 还是已满 96% 到 100%。将区分配给对象后,数据库引擎将使用 PFS 页来记录区中的哪些页已分配或哪些页可用。数据库引擎必须分配新页时,将使用此信息。保留的页中的可用空间量仅用于堆和 Text/Image 页。数据库引擎必须找到一个具有可用空间的页来保存新插入的行时,使用此信息。索引不要求跟踪页的可用空间,因为插入新行的点是由索引键值设置的。

在数据文件中,PFS 页是文件头页之后的第一页(页码为 1)。接着是 GAM 页(页码为 2),然后是 SGAM 页(页码为 3)。第一个PFS 页之后是一个大小大约为 8,000 页的 PFS 页。在第 2 页的第一个 GAM 页之后还有另一个 GAM 页(包含 64,000 个区),在第 3 页的第一个 SGAM 页之后也有另一个 SGAM 页(包含 64,000 个区)。下图显示了数据库引擎用来分配和管理区的页顺序。

下面的几段话不好理解:我的理解,估计是错的!

(IAM:是用来记录区中的页哪些来自同一对象,比如统一区中的猪都来在A农户,这样的数据就记录在IAM页中。)

“索引分配映射(IAM)”页将映射分配单元使用的数据库文件中 4 GB 部分中的区。分配单元有下列三种类型:

IN_ROW_DATA用于存储堆分区或索引分区。

LOB_DATA用于存储大型对象 (LOB) 数据类型,例如 xml、varbinary(max) 和varchar(max)。

ROW_OVERFLOW_DATA用于存储超过 8,060 字节行大小限制的 varchar、nvarchar、varbinary或 sql_variant 列中存储的可变长度数据。

  • 跟踪已修改的区

    SQL Server 使用两个内部数据结构跟踪被大容量复制操作修改的区,以及自上次完整备份后修改的区。这些数据结构极大地加快了差异备份的速度。当数据库使用大容量日志恢复模式时,这些数据结构也可以加快将大容量复制操作记录至日志的速度。与全局分配图 (GAM) 和共享全局分配图 (SGAM) 页相同,这些结构也是位图,其中的每一位代表一个单独的区。

    差异更改映射表 (DCM)

这样便可以跟踪自上次执行 BACKUP DATABASE 语句后更改过的区。如果扩展盘区的位是 1,则自上次执行 BACKUP DATABASE 语句后扩展盘区已被修改。如果位是 0,则扩展盘区没有被修改。差异备份只读取 DCM 页便可以确定已修改的区。这样大大减少了差异备份必须扫描的页数。运行差异备份所需的时间与自上次执行 BACKUP DATABASE 语句之后修改的区数成正比,而不是与整个数据库的大小成正比。

大容量更改映射表 (BCM) 
            跟踪自上次执行 BACKUP LOG 语句后,被大容量日志记录操作修改的区。如果某个扩展盘区的位是 1,表明自上次执行 BACKUP LOG 语句后,该扩展盘区已经被有日志记录的大容量复制操作修改 。如果位是 0,则该扩展盘区未被有日志记录的大容量复制操作修改。尽管所有数据库中都显示  BCM 页,但只有在数据库使用大容量日志记录恢复模式时,才会与 BCM 页有关。在此恢复模式中 ,当执行 BACKUP LOG 时,备份进程将扫描 BCM 查找已经修改的区。然后将那些区包括在日志 备份中。如果数据库从数据库备份和一系列事务日志备份恢复,便可以恢复大容量日志记录操作。在使用简单恢复模式的数据库中,BCM 页是不相关的,因为大容量日志记录操作不记入日志。在使用完整恢复模式的数据库中,BCM页同样不相关,因为该恢复模式将大容量日志记录操作视为有完整日志记录的操作。 DCM 页和 BCM 页的间隔与 GAM 和SGAM 页的间隔相同都是 64,000 个 区。在物理文件中,DCM 和 BCM 页位于 GAM 和 SGAM 页之后。




下面写一些附带的知识!

文件和文件组体系结构

SQL Server 将数据库映射为一组操作系统文件。数据和日志信息绝不会混合在同一个文件,而且一个文件只由一个数据库使用。文件组是命名的文件集合,用于帮助数据布局和管理任务。

SQL Server数据库具有三种类型的文件:

主数据文件:是数据库的起点,指向数据库中的其他文件。每个数据库都有一个主数据文件(。mdf)

次要数据文件:除主数据文件,其他的都是次要数据文件。有些数据库可能不含有次要数据文件(.ndf)。

日志文件:主要用于恢复数据库的所有信息。每个数据库必须有一个日志文件,当然也可以有多个(.ldf)。

在SQL Servcer中,数据库中所有的文件的位置都记录在数据库主文件和master数据库中。

大多时候,SQLSERVER数据库使用master数据库中的文件位置,但是在下面情况下,数据库引擎使用主文件的文件位置信息初始化master数据库中的文件位置项:

1.                    使用带有FORATTACHE或FOR ATTACH_REBUILD_LOG选项的CREATE DATADASE语句来附加数据库时。

2.                   从SQLSERVER2000版7.0版升级时。

3.                   还原master数据库。

数据文件页:SQLSERVER数据文件中的页按顺序编号,文件的首页以0开始。数据库的每个文件都有一个唯一的文件ID号。若要唯一标识数据库中的页,需要同时使用文件ID和页码。

事务日志体系结构

 1 事务日志逻辑体系结构

SQLSERVER事务日志按逻辑运行,就好像事务日志是一串日志记录一样。每条日志记录由一个日志序列号(LSN)标识。每条新日志记录均写入日志的逻辑结尾处,并使用一个比前面记录的LSN更高的LSN。日志记录按创建时的串行序列存储。每条日志记录都包含其所属事务的ID。对于每个事务,与事务相关的所有日志记录通过使用可提高事务回滚速度的向指针挨个链接在一个链中。

2 事务日志物理体系结构

 从概念上讲,日志文件是一系列日志记录。从物理上讲,日志记录序列被有序的存储在实现事务日志的物理文件集中。SQLSERER数据库引擎在内部将每一个物理日志文件分成多个虚拟日志文件。事务日志是一种回绕文件。例如:一个数据库,它包含一个分成四个虚拟日志文件的物理文件。当创建数据库的时候,逻辑日志文件从物理日志文件的始端开始。新日志记录被添加到逻辑日志的末端,然后向物理日志的末端扩张。日志截断将释放记录全部在最小恢复日志序列号(MInLSN)之前的所有虚拟日志。“MInLSN”是成功进行数据库范围内回滚所需的最早日志记录的日志序列号。当逻辑日志的末端到达物理日志文件的末端时,新的日志记录将回绕到日志文件的始端。这个循环不断重复,只要逻辑日志的末端不到达逻辑日志的始端。

* 检查点将脏数据页从当前数据库的缓冲区高速缓存刷新到磁盘上。这最大限度地减少了数据库完整恢复时必须处理的活动日志部分。

时间: 2024-10-14 11:53:44

Sql Server专题一:索引(上)的相关文章

SQL SERVER全面优化-------索引有多重要?

想了好久索引的重要性应该怎么写?讲原理结构?我估计大部分人不愿意看,也不愿意花那么多时间仔细研究.光写应用?感觉不明白原理一样不会用.举例说明?情况太多也写不全....到底该怎么写呢? 随便写吧,想到哪写到哪!  前面很多篇不管CPU.内存.磁盘.语句等等等都提到了索引的重要,我想刚刚开始学数据库的在校学生都知道索引对语句性能的重要性.但他们可能不知道,对语句的重要性就是对系统的重要性! 抛出一个问题 :你相信一条语句就能让你的大系统挂掉么? 带着问题,首先还是贴出我的座驾 最近不太喜欢红色换了

sql server数据库中索引失效的问题讨论

有关于数据库中索引失效的问题,网上也有相关的讨论.不过他们是针对oracle数据库进行讨论的.那么在sql server数据库中索引什么时候 会失效呢.总结了一下,不过我没有经过测试.没测试就没有发言权,这里仅供自己参考. 首先,所谓失效.并不真的就是这个索引被删除了.而是在这些情况下,DBMS不会检索索引列表了.执行速度和没有这个索引时的速度一样. 但是再执行另外的一条语句.同样索引可以正常起作用.所以索引的失效是针对某条sql语句的,而不是针对索引本身的.那么在哪些情况下, 确切的说是在哪类

Sql Server系列:索引基础

1. 索引概念 索引用于快速查找在某个列中某个特定值的行,不使用索引,数据库必须从第1条记录开始读完整个表,知道找出需要的行.表越大,查询数据所花费的时间越多.如果表中查询的列有索引,数据库能快速到达一个位置去查找数据,而不必遍历所有数据. 索引是一个单独的.存储在磁盘上的数据库结构,包含对数据表里所有记录的引用指针.使用索引用于快速找出一个或多个列中有特定值的行,对相关列使用索引是降低查询操作时间的最佳途径.索引包含由表或试图中的一列或多列生成的键. 索引的优点: ◊ 通过创建唯一索引,可以保

转载: SQL Server中的索引

http://www.blogjava.net/wangdetian168/archive/2011/03/07/347192.html 1 SQL Server中的索引 索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度.索引包含由表或视图中的一列或多列生成的键.这些键存储在一个结构(B 树)中,使 SQL Server 可以快速有效地查找与键值关联的行. 表或视图可以包含以下类型的索引: 聚集索引 聚集索引根据数据行的键值在表或视图中排序和存储这些数据行.索引定义中包含聚集索

SQL Server 非聚集索引的覆盖,连接,交叉和过滤 <第二篇>

在SQL Server中,非聚集索引其实可以看做是一个含有聚集索引的表,但相对实际的表来说,非聚集索引中所存储的表的列数要少得多,一般就是索引列,聚集键(或RID).非聚集索引仅仅包含源表中的非聚集索引的列和指向实际物理表的指针. 一.非聚集索引之INCLUDE 非聚集索引其实可以看做一个含有聚集索引的列表,当这个非聚集索引中包含了查询所需要的所有信息的时候,则就不再需要去查基本表,仅仅做非聚集索引就能够得到所需要的数据.INCLUDE实际上也能称为覆盖索引,但它不影响索引键的大小. 先来看下面

SQL Server中的索引

1 SQL Server中的索引 索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度.索引包含由表或视图中的一列或多列生成的键.这些键存储在一个结构(B 树)中,使 SQL Server 可以快速有效地查找与键值关联的行. 表或视图可以包含以下类型的索引: 聚集索引 聚集索引根据数据行的键值在表或视图中排序和存储这些数据行.索引定义中包含聚集索引列.每个表只能有一个聚集索引,因为数据行本身只能按一个顺序排序. 只有当表包含聚集索引时,表中的数据行才按排序顺序存储.如果表具有聚集索

细说Sql Server中的视图(上)转载

原文:细说Sql Server中的视图(上)http://www.cnblogs.com/xbf321/archive/2009/06/16/view_in_sqlserver.html 1,什么是视图? 2,为什么要用视图: 3,视图中的ORDER BY; 4,刷新视图: 5,更新视图: 6,视图选项: 7,索引视图: 细说Sql Server中的视图(下)   应大家要求已在“细说Sql Server中的视图(上)”中添加“为什么要用视图”一小节. 1.什么是视图 视图是由一个查询所定义的虚

SQL Server 非聚集索引的覆盖,连接交叉和过滤

一.非聚集索引之INCLUDE 非聚集索引其实可以看做是一个ie含有聚集索引的列表,当这个聚集索引中包含了查询所需要的所有信息的时候,则就不再需要去查基本表,仅仅做非聚集索引就能得到所需要的数据,INCLUDE实际也能称为覆盖索引,但它不影响索引键的大小. INCLUDE最好在以下情况中使用: 你不希望增加索引键的大小,但是仍然希望有一个覆盖索引: 你打算索引一种不能被索引的数据类型(除了文本.ntext和图像): 你已经超过了一个索引的关键字列的最大数量(但是最好避免这个问题): 二.非聚集索

SQL Server 列存储索引强化

SQL Server 列存储索引强化 SQL Server 列存储索引强化... 1 1. 概述... 1 2.背景... 2 2.1 索引存储... 2 2.2 缓存和I/O.. 2 2.3 Batch处理方式... 2 3 聚集索引... 3 3.1 提高索引创建... 4 3.2 采样的支持... 4 3.3 BookMark的支持... 4 3.4 其他加强... 4 4 更新处理... 4 4.1 随机插入... 6 4.2 批量插入... 6 4.3 删除和更新... 6 4.4 对

T-SQL查询高级--理解SQL SERVER中非聚集索引的覆盖,连接,交叉和过滤

写在前面:这是第一篇T-SQL查询高级系列文章.但是T-SQL查询进阶系列还远远没有写完.这个主题放到高级我想是因为这个主题需要一些进阶的知识作为基础..如果文章中有错误的地方请不吝指正.本篇文章的内容需要索引的知识作为基础. 简介 在SQL SERVER中,非聚集索引其实可以看作是一个含有聚集索引的表.但相比实际的表而言.非聚集索引中所存储的表的列数要窄很多,因为非聚集索引仅仅包含原表中非聚集索引的列和指向实际物理表的指针. 并且,对于非聚集索引表来说,其中所存放的列是按照聚集索引来进行存放的