[笔记整理]SQL Server 索引碎片 和 重建索引
铺垫知识点:
数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘。既键值的逻辑顺序决定了表中相应行的物理顺序
多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲写入速度
页 为最小单位 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 索引碎片 和 重建索引的更多相关文章
- SQL Server通过整理索引碎片和重建索引提高速度
		
本文章转载:http://database.51cto.com/art/201108/282408.htm SQL Server数据库中,当索引碎片太多时,就会拖慢数据库查询的速度.这时我们可以通过整 ...
 - SQL Server 锁实验(重建索引)
		
昨晚某现场报一个重建索引失败的问题,远程查看后发现是自动收缩的内部会话引发的锁申请超时,突然想起来自己的加锁实验还没完成索引重建部分,今天有空正好做一下: USE [数据库名] GO ALTER IN ...
 - SQL Server数据库所有表重建索引
		
USE My_Database;DECLARE @name varchar(100) DECLARE authors_cursor CURSOR FOR Select [name] from s ...
 - SQL Server 2016 —— 聚集列存储索引的功能增强
		
作者 Jonathan Allen,译者 邵思华 发布于 2015年6月14日 聚集列存储索引(CC Index)是SQL Server 2014中两大最引 ...
 - SQL Server 查询性能优化——创建索引原则
		
索引是什么?索引是提高查询性能的一个重要工具,索引就是把查询语句所需要的少量数据添加到索引分页中,这样访问数据时只要访问少数索引的分页就可以.但是索引对于提高查询性能也不是万能的,也不是建立越多的索引 ...
 - SQL索引管理器 - 用于SQL Server和Azure上的索引维护的免费GUI工具
		
我作为SQL Server DBA工作了8年多,管理和优化服务器的性能.在我的空闲时间,我想为宇宙和我的同事做一些有用的事情.这就是我们最终为SQL Server和Azure 提供免费索引维护工具的方 ...
 - SQL Server数据库性能优化之索引篇【转】
		
http://www.blogjava.net/allen-zhe/archive/2010/07/23/326966.html 性能优化之索引篇 近期项目需要, 做了一段时间的SQL Server性 ...
 - SQL Server查询性能优化——覆盖索引(二)
		
在SQL Server 查询性能优化——覆盖索引(一)中讲了覆盖索引的一些理论. 本文将具体讲一下使用不同索引对查询性能的影响. 下面通过实例,来查看不同的索引结构,如聚集索引.非聚集索引.组合索引等 ...
 - SQL Server查询性能优化——创建索引原则(一)
		
索引是什么?索引是提高查询性能的一个重要工具,索引就是把查询语句所需要的少量数据添加到索引分页中,这样访问数据时只要访问少数索引的分页 就可以.但是索引对于提高查询性能也不是万能的,也不是建立越多的索 ...
 
随机推荐
- CDH部署日志
			
CDH部署时出现如图所示的错误 可去服务器查看:/opt/cm-5.5.0/run/cloudera-scm-agent/process/ccdeploy_hbase-conf_etchbasecon ...
 - 调试maven源代码
			
下载源代码,导入idea 运行MavenCli ,设置vm参数 -Dclassworlds.conf=/Users/fsq/Downloads/apache-maven-3.6.2.0/bin/m2. ...
 - 浅谈pipreqs组件(自动生成需要导入的模块信息)
			
简介 pipreqs的作用 一起开发项目的时候总是要搭建环境和部署环境的,这个时候必须得有个python第三方包的list,一般都叫做requirements.txt. 如果一个项目使用时virtua ...
 - 【足迹C++primer】38、关联容器操作(2)
			
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/cutter_point/article/details/35244805 关联容器操作(2) map ...
 - C#的Installer生成的msi的安装文件,安装新版本时提示:已经安装了该产品的另一个版本。无法继续安装此版本
			
之前折腾了个C#的项目: WLW (Windows Live Writer) Plugin–InsertSkydriveFiles 然后又弄了个对应的Installer: [已解决]给一个C#的Dll ...
 - 脱离JVM? Hadoop生态圈的挣扎与演化
			
本文由知乎<大数据应用与实践>专栏 李呈祥授权发布,版权所有归作者,转载请联系作者! 新世纪以来,互联网及个人终端的普及,传统行业的信息化及物联网的发展等产业变化产生了大量的数据,远远超出 ...
 - 详解MySQL第一篇—MySQL简要介绍及DDL语句
			
背景:近几年,开源数据库逐渐流行起来.由于具有免费使用.配置简单.稳定性好.性能优良等优点,开源数据库在中低端应用上占据了很大的市场份额,而 MySQL 正是开源数据库中的杰出代表.MySQL 数据库 ...
 - [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts
			
地址:http://codeforces.com/gym/101194 题目:略 思路: 这题做法挺多的,可以sam也可以后缀数组,我用sam做的. 1.我自己yy的思路(瞎bb的) 把第一个串建立s ...
 - 使用自签名SSL证书配置HTTPS,解决浏览器提示不安全警告
			
项目测试过程中需要将应用从HTTP升级到HTTPS,浏览了网上一些帖子,参考<WebLogic11g-单双向SSL配置(以Springside3为例)>一文使用openssl工具来自建CA ...
 - windows AD域安装及必要设置
			
一.安装AD域 运行dcpromo命令,安装AD域. 步骤: 1.win+R 2.dcpromo 图例: 百度百科关于“dcpromo”解释: dcpromo命令是一个“开关”命令.如果Windows ...