数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘。既键值的逻辑顺序决定了表中相应行的物理顺序

多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲写入速度

页 为最小单位 8kb

区 物理连续的页(8页)的集合

内部碎片 数据库页内部产生的碎片,外部反之

碎片的产生:

有一个表里有8条数据,已经将一页填满,这个时候要插入第九条数据,页也就分裂了。这就产生了内部碎片。如下图所示(excel示意一下  懒癌晚期)

注: 不会将9单独分到第二页,索引B+树存储,会让存储尽量平衡,以减少检索层级。

且一般情况下SQL Server数据库默认设置有20%的填充因子(可设置),既新建页80%存数据,20%为update和insert预留。

另外,在插入1~8之后  9之前,很可能数据库在这段时间有N多新增数据,也就是在物理结构上 页1 和 页2 无法连续。这就无法避免的产生了外部碎片

查看碎片情况:

用到这个极重要的 sys.dm_db_index_physical_stats 动态函数,传闻数据库引擎在思考自己如何高效的查询数据的时候都要来这瞅瞅。

太高深的我并不会,目前我就看以下几个,其他参照MSDN

avg_fragmentation_in_percent =>当前索引碎片百分比 【如果碎片小于10%~20%,碎片不太可能会成为问题,如果索引碎片在20%~40%,碎片可能成为问题,但是可以通过索引重组来消除索引解决,大规模的碎片(当碎片大于40%),可能要求索引重建。】

avg_page_space_used_in_percent =>所有页中使用的可用数据存储空间的平均百分比

page_count =>索引或数据页的总数

 select *  from  sys.dm_db_index_physical_stats(DB_ID() ,object_id('agent') ,NULL,NULL,NULL)

碎片的解决:

1.删除索引并重建

  这种方式有如下缺点:

  索引不可用:在删除索引期间,索引不可用。

  阻塞:卸载并重建索引会阻塞表上所有的其他请求,也可能被其他请求所阻塞。

  对于删除聚集索引,则会导致对应的非聚集索引重建两次(删除时重建,建立时再重建,因为非聚集索引中有指向聚集索引的指针)。

  唯一性约束:用于定义主键或者唯一性约束的索引不能使用DROP INDEX语句删除。而且,唯一性约束和主键都可能被外键约束引用。在主键卸载之前,所有引用该主键的外键必须首先被删除。尽管可以这么做,但这是一种冒险而且费时的碎片整理方法。

  基于以上原因,不建议在生产数据库,尤其是非空闲时间不建议采用这种技术。

  2.使用DROP_EXISTING语句重建索引

  为了避免重建两次索引,使用DROP_EXISTING语句重建索引,因为这个语句是原子性的,不会导致非聚集索引重建两次,但同样的,这种方式也会造成阻塞。

CREATE UNIQUE CLUSTERED INDEX IX_C1 ON t1(c1)
WITH (DROP_EXISTING = ON)

缺点:

  阻塞:与卸载重建方法类似,这种技术也导致并面临来自其他访问该表(或该表的索引)的查询的阻塞问题。

  使用约束的索引:与卸载重建不同,具有DROP_EXISTING子句的CREATE INDEX语句可以用于重新创建使用约束的索引。如果该约束是一个主键或与外键相关的唯一性约束,在CREATE语句中不能包含UNIQUE。

  具有多个碎片化的索引的表:随着表数据产生碎片,索引常常也碎片化。如果使用这种碎片整理技术,表上所有索引都必须单独确认和重建。

  3.使用ALTER INDEX REBUILD语句重建索引

  使用这个语句同样也是重建索引,但是通过动态重建索引而不需要卸载并重建索引.是优于前两种方法的,但依旧会造成阻塞。可以通过ONLINE关键字减少锁,但会造成重建时间加长。

  阻塞:这个依然有阻塞问题。

  事务回滚:ALTER INDEX REBUILD完全是一个原子操作,如果它在结束前停止,所有到那时为止进行的碎片整理操作都将丢失,可以通过ONLINE关键字减少锁,但会造成重建时间加长。

  4.使用ALTER INDEX REORGANIZE

  这种方式不会重建索引,也不会生成新的页,仅仅是整理叶级数据,不涉及非叶级,当遇到加锁的页时跳过,所以不会造成阻塞。但同时,整理效果会差于前三种。

  4种索引整理技术比较:

特性/问题 卸载并重建索引 DROP_EXISTING ALTER INDEX REBUILD ALTER INDEX REORGANIZE
在聚集索引碎片整理时,重建非聚集索引 两次
丢失索引
整理具有约束的索引的碎片 高度复杂 复杂性适中 简单 简单
同时进行多个索引的碎片整理
并发性 中等,取决于冰法用户活动
中途撤销 因为不使用事务,存在危险 进程丢失 进程丢失 进程被保留
碎片整理程度 中到低
应用新的填充因子
更新统计

参考:  SQL Server索引的维护 - 索引碎片、填充因子 <第三篇>

       msdn sys.dm_db_index_physical_stats (Transact-SQL)

SQL Server 索引碎片产生原理重建索引和重新组织索引的更多相关文章

  1. SQL Server调优系列进阶篇(如何维护数据库索引)

    前言 上一篇我们研究了如何利用索引在数据库里面调优,简要的介绍了索引的原理,更重要的分析了如何选择索引以及索引的利弊项,有兴趣的可以点击查看. 本篇延续上一篇的内容,继续分析索引这块,侧重索引项的日常 ...

  2. SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

    前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...

  3. SQL server学习(四)T-SQL编程之事务、索引和视图

    今天来分享下T-SQL高级编程中的事务.索引.视图,可以和之前的SQL server系列文章结合起来. 一.事务 事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个 ...

  4. SQL Server AlwaysOn架构及原理

    SQL Server AlwaysOn架构及原理 SQL Server2012所支持的AlwaysOn技术集中了故障转移群集.数据库镜像和日志传送三者的优点,但又不相同.故障转移群集的单位是SQL实例 ...

  5. sql server mdf碎片级数据库修复,数据库碎片级提取

    sql server mdf碎片级数据库修复,数据库碎片级提取   大家都知道MDF数据库文件一般都比较大,在磁盘中往往被存放到不连续的逻辑簇中,久而久之就形成了文件碎片,当文件被误删除或者格式化后, ...

  6. SQL SERVER大话存储结构(2)_非聚集索引如何查找到行记录

              如果转载,请注明博文来源: www.cnblogs.com/xinysu/   ,版权归 博客园 苏家小萝卜 所有.望各位支持!      1 行记录如何存储     这里引入两个 ...

  7. SQL Server -- 回忆笔记(四):case函数,索引,子查询,分页查询,视图,存储过程

    SQL Server知识点回忆篇(四):case函数,索引,子查询,分页查询,视图,存储过程 1. CASE函数(相当于C#中的Switch) then '未成年人' else '成年人' end f ...

  8. SQL Server 调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

    前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...

  9. SQL Server数据库碎片整理

    碎片产生   在SQL Server中,存储数据的最小单位是页,每一页所能容纳的数据为8060字节.而页的组织方式是通过B树结构  SQL Server向每个页内存储数据的最小单位是表的行(Row)  ...

随机推荐

  1. Vmware安装Ubuntu ==> 连网成功

    由于工作需要,得把NS3安装到内网服务器中,大家知道这个是不能连接外网的,学校又没有Ubuntu高校源.NS3要先安装一大堆的依赖,让人头痛的是在内网里有没发以终端指令形式安装,针对这种麻烦,找到两个 ...

  2. arm-none-eabi-gcc编译报错:exit.c:(.text.exit+0x16): undefined reference to `_exit'

    该问题的出现是链接文件导致的,是不同的gcc交叉编译器支持的链接文件不同造成的,有几种方法可以解决这个问题. 方法一:更换arm-none-eabi-gcc的版本,这个一般是新的gcc编译器才会抱着错 ...

  3. Python内置函数(20)——exec

    英文文档: exec(object[, globals[, locals]]) This function supports dynamic execution of Python code. obj ...

  4. 纽约工作日志流水账 Day 2

    今天本来想一觉睡到早上7点,结果凌晨2点30就行了,然后就各种睡不着了. 挣扎到5点,饿的不行,就起来找东西吃,发现冰箱里东西真不少. 8点半,开始和亢爷做早饭,自制俩汉堡,样子略丑, 味道还不错.这 ...

  5. Chorme浏览器渲染MathJax时出现竖线的解决方法

    Chorme浏览器渲染MathJax时出现竖线的原因分析与解决方法 查资料知,Chorme中显示MathJax时出现竖线的原因如下: 新版的Chorme浏览器在解析css时,会对其中的值进行向上取整( ...

  6. 前端笔记之JavaScript(十二)缓冲公式&检测设备&Data日期

    一.JavaScript缓冲公式ease 原生JS没有自己的缓冲公式,但是你要自己推理的话,必须要懂一些数学和物理公式: 让div用100毫秒(帧),从left100px的位置变化到left800px ...

  7. Chapter 5 Blood Type——6

    "Yes — giving up trying to be good. I'm just going to do what I want now, and let the chips fal ...

  8. 痞子衡嵌入式:飞思卡尔Kinetis开发板OpenSDA调试器那些事(上)- 背景与架构

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis MCU开发板板载OpenSDA调试器(上篇). 众所周知,嵌入式软件开发几乎离不开调试器,因为写一个稍有代码规模 ...

  9. Captcha服务(后续2)— 改造Captcha服务之Asp.Net Core项目中如何集成TypeScript

    环境准备 .Net Core 版本:下载安装.Net Core SDK,安装完成之后查看sdk版本 ,查看命令dotnet --version,我的版本是2.2.101 IDE: Visual Stu ...

  10. 使用asp.net mvc + entityframework + sqlServer 搭建一个简单的code first项目

    步骤: 1. 创建一个asp.net mvc 项目 1.1 项目创建好结构如下 2 通过vs安装EntityFramework框架 install-package entityframework 3. ...