【译】索引进阶(十一):SQL SERVER中的索引碎片【上篇】

原文链接:传送门。

 

第十章节我们分析了索引的内部结构。有了这些关于索引结构的知识,我们便可以分析索引碎片了:其产生的原因,如何防止,以及何时可以不去关注它们。

一些背景知识 / 复习

以下知识对于理解索引碎片来说是至关重要的,有些知识在之前的章节中都已经出现过,比如使用索引来返回数据的场景。在本节,我们的场景是索引的维护,因此,一些旧的知识在此会重复出现,而同时会增加一些新的知识。

每张表要么是个堆要么是个聚集索引。

如果表是个堆,那么其非聚集索引的书签部分便是一个行标识符(RID),如果表是一个聚集索引,那么非聚集索引的书签部分便是其聚集索引的索引键值。

索引条目存储在页中,8个物理上连续的页组成一个区。

索引层级从底部,从0开始计算,因此叶子层级总是第0层,而最低的中间层节点总是第1层,根页总是自己成为一个层级,并且它具有最高的层级数。

扫描整个索引意味着叶子层级的所有页都会被读且仅会被读一次。每一个页包含了一个指向上一个和下一个页的指针。页的逻辑顺序和物理顺序或许是不一致的。指向下一个页的指针后续会指向位于同一个区的页,或者指向几百个页之前的一个页(也可能是之后),甚至于指向不同文件的一个页。

页的物理顺序和逻辑顺序越一致,扫描整个索引所需要的IO数就越少。当两个顺序一致的时候,SQL SERVER每次IO可读取一整个区或者更多。同样的,页的物理顺序和逻辑顺序越相关,那么使用的预读数便越多(预读:在使用之前,先将页存入内存)。不管是扫描整个索引,还是只扫描索引的一部分,这都是确定无疑的。

为了返回一个索引条目,从根节点开始,每个层级的一个页都必须被访问到。这种操作的性能不会被索引物理顺序和逻辑顺序的相关性所影响。

记住了这些信息,我们来检查索引碎片这个主题。

什么是碎片?

索引碎片来自于两种情形:内部碎片和外部碎片。决定索引碎片(不管是内部碎片或者是外部碎片)的最好工具是 sys.dm_db_index_physical_stats这个动态管理函数。因为这个函数显示的是索引ID,而不是索引的名称,查询常常将它与视图sys.indexes 连接起来,从而在输出中包含索引名称,本章节我们将使用这个函数,首先我们梳理下内部碎片,然后再陈述下外部碎片。

 内部碎片

每个页都会包含一定数量的索引条目,那并不意味着每个页总是包含最大数量的条目数。为了本章后续会讲到的一些理由,通常一个索引页并不总是完全充满的。当我们说一个索引包含内部碎片时,我们就意味着这个页并不是完全充满的。在一个索引中,每页占据的空间的数量体现了索引的内部碎片,同时也体现了一个索引的平均页覆盖率。注意覆盖率测量得越高,内部碎片便越少。一个100%充满的页是每有内部碎片的。内部碎片通常以一个百分比的形式被报告出来,并且其体现了字节数上的覆盖率而不是条目上的覆盖率。因此一个覆盖率是96%的索引页或许是完全充满的。那就是说,4%的页空间或许不是足够的空间用来添加一个新的条目。当页的空间被头信息及页的偏移指针占据的时候,一个各个条目相对比较大的页或许在90%,80%,甚至更少的时候就会充满。

sys.dm_db_index_physical_stats函数在它的avg_page_space_used_in_percent输出列报告了索引的内部碎片。显示在列表1的查询,它检查了SalesOrderDetail表的聚集索引,显示了其内部碎片信息。

SELECT IX.name AS 'Name', PS.index_level AS 'Level', PS.page_count AS 'Pages', PS.avg_page_space_used_in_percent AS 'Page Fullness (%)'FROM sys.dm_db_index_physical_stats( DB_ID(), OBJECT_ID('Sales.SalesOrderDetail'), DEFAULT, DEFAULT, 'DETAILED') PSJOIN sys.indexes IXON IX.OBJECT_ID = PS.OBJECT_ID AND IX.index_id = PS.index_id WHERE IX.name = 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID';
GO

 列表1:  一个返回内部碎片信息的查询

 

这个查询对于索引的每个层级都会返回一行输出,如图表1中所显示的。

 图表1:内部碎片查询的输出

这个特定查询的主题是聚集索引,因此索引的页层级是表的数据行,第0层的输出,也就是以上输出的第一行,告诉我们表的数据行分散在1234个页中,其平均充满率是99%。换句话说,这个表具有很小数量的内部碎片。

外部碎片

与内部碎片相对的,外部碎片指的是一个索引逻辑顺序与物理顺序的不一致。它同样被报告为一个百分比。引用微软技术网的原文,它指的是一个索引的叶子节点中无序页(out-of-order pages)的百分比,所谓的无序页指的是如果当前页物理上分配的紧邻的页不是偏移指针所指向的页。那么当前页便称之为无序页。虽然官方定义将定义本身限制在叶子层级,你将注意到 sys.dm_db_index_physical_stats函数能够返回索引所有层级的碎片信息。

我们注意到,与内部碎片不同的是,一个高的数值意味着更大数量的外部碎片,因此一个具有100%外部碎片的索引几乎完全是外部碎片,也就是说,它的逻辑顺序与物理顺序完全没有任何关联性。

考虑图片2演示的一个简单的例子。一个16个页的索引占据了起始于数据库文件40页和56页的区。除了每个区的最后一个页,任何一个页的下一页指针指向区中的下一页。而第一个区的最后一页指向第二个区的第一页。第二个区的最后一页没有指向任何页,因为其是索引的最后一个页。

在这个例子中,无序页的数量是0,虽然第8,9页在文件中是物理上不连续的,它们在分配给索引的空间内是连续的,因此这个例子的外部碎片是0。

    图2: 没有外部碎片的索引

在另一方面,图3展示了一样的表,但是具有一些无序页,前三个页逻辑上是连续的,但是在那之后其逻辑顺序和物理顺序便没有任何相关性。

    图3:具有外部碎片的索引

任何下一页指针如果没有指向索引的物理上分配的下一个页的话,便是一个无序指针,不管其向前指,向后指,在区内,跨区,甚至于跨越整个文件。

为了演示如何获取一个索引的外部碎片信息,我们将之前的查询做两处改动。因为外部索引涉及了页之间的关系,而不是页的内容,它能够被扫描索引的第一层定义出来,而不用扫描大得多的索引的叶子层级。我们将函数的最后一个参数从DETAILED 修改为LIMITED (or DEFAULT),从而告知SQL SERVER叶子节点扫描不是必要的。

同时我们修改SELECT子句包含一些稍微不同的列集,它们能够提供索引的外部碎片信息,最终修改后的查询显示如下:

SELECT IX.name AS 'Name'
, PS.index_level AS 'Level'
, PS.page_count AS 'Pages'
, PS.avg_fragmentation_in_percent AS 'External Fragmentation (%)'
, PS.fragment_count AS 'Fragments'
, PS.avg_fragment_size_in_pages AS 'Avg Fragment Size'
FROM sys.dm_db_index_physical_stats(
DB_ID(),
OBJECT_ID('Sales.SalesOrderDetail'),
DEFAULT, DEFAULT, 'LIMITED') PS
JOIN sys.indexes IX
ON IX.OBJECT_ID = PS.OBJECT_ID AND IX.index_id = PS.index_id
WHERE IX.name = 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID';
GO

因为我们给最后一个参数指定了LIMITED,我们将得到一行输出,如图4所示。

  图4:外部碎片查询输出

 这个结果告诉我们这个索引的大小是1234页,包含了20个碎片,平均每个碎片的大小是61.7页。如同砍一块木头导致两块,砍两下导致3块,一个无序的下一页指针导致两个碎片,两个无序指针导致三个碎片,等等。因此我们的索引含有20-1 =19个页包含无序指针,平均下来,当以逻辑数据扫描这个索引的时候,在各个无序页之间61个连续的页会发生。这是一个包含很少外部碎片的索引。

SSMS的索属性窗口,显示在图5,通过执行一个与我们之前执行的查询类似的查询来获取它的信息,其Page fullnessTotal fragmentation分别指的是索引的内部碎片和外部碎片。

   图5:SSMS的索引属性窗口

本节我们介绍了索引碎片的基础知,下一节我们将深入讨论索引碎片,包括其如何产生,如何防止,以及一些通用的实践模式。

To be continued...

 

转载于:https://www.cnblogs.com/qianxingmu/p/10633503.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411884.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maverick.Net介绍 (来自http://www.cnblogs.com/RicCC/archive/2006/09/17/506890.html)

Maverick.Net介绍 Maverick.Net是Java社区开源MVC Web框架Maverick的.Net版本,相关资料可以查看项目主页。不管Maverick.Net的是非好坏,了解一下它的思想还是不错的。下面的内容是对Maverick.Net整体做一个简单的介绍,以求能够从全局的角度了…

惊了!最通俗易懂的Djongo入门竟然在这里!

Django简介python下有多款不同的web框架,Django是最有代表行的一种。许多成功的网站和app都基于djanfo。django是一个开源的web应用框架,由python写成。django采用了MVC的软件设计模式,即模型M,视图V和控制器C。Django特点强大的数据库功能&a…

linux z是什么文件夹,Linux znew初学者命令实例教程

原标题:Linux znew初学者命令实例教程您是否知道Linux提供了一种将.Z文件重新压缩为.gz文件的方法? 是的,znew命令可以让你这样做。 在本教程中,我们将使用一些易于理解的示例讨论此命令行实用程序的基础知识。 但在我们这样做之前…

使用X.509数字证书加密解密实务(一)-- 证书的获得和管理

一、 获得证书... 21、 从CA获得... 22、 从windows2003证书服务中获得... 23、 使用makecert工具获得... 2二、 证书的保存... 21、 保存在证书存储区... 22、 以文件形式保存... 42.1. 带有私钥的证书... 42.2. …

JVM分析

在运行java进程是,可以通过jps命令查看进程PID,使用java的同居jmap命令可以得到jvm的dump文件; 在网上找了两种方式获取dump文件 获取JVM的dump文件的两种方式:转载来源https://www.cnblogs.com/liu-ke/p/6622350.html【流柯】 1.…

linux组类型,LINUX用户以及用户组

转载博文:https://blog.csdn.net/xietansheng/article/details/800446200、用户、组、文件权限 常用命令:类型举例用户who, whoami, su, useradd, userdel, passwd, usermod, /etc/passwd组groupadd, groupdel, groupmod, /etc/group文件chmod, chown, chgrp其他sudo, exitPS:1…

linux安装Git依赖的包出错,技术|Linux有问必答:如何在Linux上安装Git

问题: 我尝试从一个Git公共仓库克隆项目,但出现了这样的错误提示:“git: command not found”。 请问我该如何在某某发行版上安装Git?Git是一个流行的开源版本控制系统(VCS),最初是为Linux环境开发的。跟CVS或者SVN这些版本控制系…

1社会心理学---感知情境

1小便池放一只苍蝇减少百分之八十的人不文明行为 2电梯中所有人背靠有人就会背靠 3结论 4社会心理学

史上最扯Java图形绘制(J2SE)之一JAVA动画效果

史上最扯Java图形绘制(J2SE)之一JAVA动画效果 很多主一听说Java界面,一水的头大外带血压高,兄弟我倒觉得没什么必要。其实Java这东西吧,就简便性和其初衷而言,真他妈就在GUI 这地界是有优势的,单…

linux 3.11 虚拟摄像头 驱动,摄像头万能驱动-万能视频驱动-摄像头万能驱动下载 v2011.3官方版-完美下载...

摄像头万能驱动收录了N多常用驱动,且适用于80%的摄像头,如:华硕、罗技、创新、联想、戴尔等品牌,智能化的摄像头设备识别和驱动安装,小白也能操作,同时摄像头万能驱动也是装机人员必备驱动盘,一…

linux mate eth0已下线,Linux Mint 18 Cinnamon 版和 MATE 版已经可以下载了

在今天早些时候,Linux Mint[1] 项目负责人 Clement Lefebvre 将 ISO 镜像放到了网上,它首先出现在了爱尔兰的镜像网站[2],看起来已经是最终的产品形态了。截止到写这篇文章时,在 Linux Mint 网站上还没有发布官方通告,…

使用脚本动态操作 SVG 文档

本教程适用于那些希望使用可伸缩向量图形(SVG)创建交互式 SVG 图形的开发人员。它讨论了使用ECMAScript(JavaScript)对现有的 SVG 图像进行实时操作得技术。本文主要介绍在 SVG 中通过编程实现动态操作 SVG 图像的知识。 SVG 图像…