SQL Server 性能篇- 碎片
本文分为两个问题: 第一,碎片是什么;第二,碎片怎么处理;
现在,来找解决这两个问题:
一、碎片是什么
说到碎片,就要提到索引了,索引用着挺爽的啊!是的,一旦索引建立,我们搜索数据的效率就提高了;然后我们就要想一想了,索引将我们的数据排序了,不管聚集还是非聚集索引总归是将数据排序了。这些数据给排序了,那么问题来了,我们个这些已经排序的数据进行插入操作会产生什么后果?人家本来好好排着队呢!插队的来了!
假设一群很瘦的人在排队,突然插入一个胖子,且不说胖子捣乱了正常的排序规则,胖子插进队伍中,一个人占了两个人的空间,这个时候对于瘦的人来说,胖子浪费了一个人的空间,如果不断的有胖子插队,浪费的空间会越来越多。浪费的空间在数据库中就是碎片!这里有一篇博客,举例说明了在数据库中碎片的产生。在数据库中,数据存在于页内,一个页是8K,索引已经建立的前提下,这8K数据是好好的排序待着的,然后,向这个页中插入一条数据(比原来数据中最大行还要大),这时后面数据就会遵循B树规则开始移动,因为这个页已经满了,后面的数据就会被挤出去若干条到下一页,如果下一页也是满的,依次往下排,这对于数据库来说消耗是很大的。这个过程中,在最初的页中,就会产生碎片,因为插入的数据偏大,导致后面的数据后移到别人页,就会空出空间了,而这部分空间就暂时没法利用,造成碎片。这种情况属于内部碎片,是页内的。因为在这个区中可能,页与页之间还是连续的。仅仅是最初的那个页中的数据是断续的。首先,插入数据造成数据移动消耗大,另外,在页中打乱了页内的排序,造成查询性能下降。这就是碎片造成影响。
另一种,情况就是插入的数据使页与页之间造成断续,比如,插入的数据正好在页中最后一行,被挤出到别的页的数据,与原来的页之间没有了连续,这后果就更严重了,这种情况就是外部的碎片。
这样看,在一定程度上索引的性能就下降了。就需要重新维护索引了。怎么维护呢?将原来的索引删除,重新构建?这种做法,在某些场景中是很合适的。比如,插入的动作比较少的情况下,在合适的时候,重现构建索引是可取的。除了,重构呢?
二、碎片怎么处理
我们要进行索引的维护,首先要知道一些查询数据库性能的语句,来获取当前数据库的性能,做出判断之后,采取不同的措施。
此时我们用到的就是元数据函数sys.dm_db_index_physical_stats,它有助于确定数据库中的页和区段有多满。使用这个函数得到当前数据的一些性能信息。图片来源于参考博客。

下面,先来说第一种类似于重建:
1、使用DROP_EXISTING语句重建索引:为了避免重建两次索引,使用DROP_EXISTING语句重建索引,因为这个语句是原子性的,不会导致非聚集索引重建两次,但同样的,这种方式也会造成阻塞。缺点:阻塞:与卸载重建方法类似,这种技术也导致并面临来自其他访问该表(或该表的索引)的查询的阻塞问题。、
使用约束的索引:与卸载重建不同,具有DROP_EXISTING子句的CREATE INDEX语句可以用于重新创建使用约束的索引。如果该约束是一个主键或与外键相关的唯一性约束,在CREATE语句中不能包含UNIQUE。
具有多个碎片化的索引的表:随着表数据产生碎片,索引常常也碎片化。如果使用这种碎片整理技术,表上所有索引都必须单独确认和重建。
CREATE UNIQUE CLUSTERED INDEX IX_C1 ON t1(c1)
WITH (DROP_EXISTING = ON)
2、用ALTER INDEX REBUILD语句重建索引:使用这个语句同样也是重建索引,但是通过动态重建索引而不需要卸载并重建索引.是优于前两种方法的,但依旧会造成阻塞。可以通过ONLINE关键字减少锁,但会造成重建时间加长。
阻塞:这个依然有阻塞问题。
事务回滚:ALTER INDEX REBUILD完全是一个原子操作,如果它在结束前停止,所有到那时为止进行的碎片整理操作都将丢失,可以通过ONLINE关键字减少锁,但会造成重建时间加长。
3、使用ALTER INDEX REORGANIZE:这种方式不会重建索引,也不会生成新的页,仅仅是整理叶级数据,不涉及非叶级,当遇到加锁的页时跳过,所以不会造成阻塞。但同时,整理效果会差于前三种。

4、填充因子:填充因子的概念可以理解为预留一定的空间存放插入和更新新增加的数据,以避免页拆分。 填充因子值的选择:
如何设置填充因子的值并没有一个公式或者理念可以准确的设置。使用填充因子虽然可以减少更新或者插入时的分页,但同时因为需要更多的页,所以降低了查询的性能和占用更多的磁盘空间.如何设置这个值进行trade-off需要根据具体的情况来看。具体情况要根据对于表的读写比例来看,我这里给出我认为比较合适的值:
- 当读写比例大于100:1时,不要设置填充因子,100%填充
- 当写的次数大于读的次数时,设置50%-70%填充
- 当读写比例位于两者之间时80%-90%填充
本文参考: SQL Server索引的维护 - 索引碎片、填充因子 <第三篇>
SQL Server 性能篇- 碎片的更多相关文章
- 改进SQL Server 性能 - 索引碎片重建
我们先来看一个用户表上的索引碎片情况: DBCC SHOWCONTIG scanning 'Lead' table...Table: 'Lead' (1422628111); index ID: 1, ...
- SQL Server 性能优化详解
故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...
- 【目录】sql server 进阶篇系列
随笔分类 - sql server 进阶篇系列 sql server 下载安装标记 摘要: SQL Server 2017 的各版本和支持的功能 https://docs.microsoft.com/ ...
- 初涉SQL Server性能问题(4/4):列出最耗资源的会话
在上3篇文章里,我们讨论了列出反映服务器当前状态的不同查询. 初涉SQL Server性能问题(1/4):服务器概况 初涉SQL Server性能问题(2/4):列出等待资源的会话 初涉SQL Ser ...
- 初涉SQL Server性能问题(3/4):列出阻塞的会话
在 初涉SQL Server性能问题(2/4)里,我们讨论了列出等待资源或正运行的会话脚本.这篇文章我们会看看如何列出包含具体信息的话阻塞会话清单. /************************ ...
- SQL Server 性能调优培训引言
原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...
- SQL Server 性能优化之——系统化方法提高性能
SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...
- sql server 性能调优之 资源等待 LCk
一. 概述 这次介绍实例级别资源等待LCK类型锁的等待时间,关于LCK锁的介绍可参考 “sql server 锁与事务拨云见日”.下面还是使用sys.dm_os_wait_stats 来查看,并找出 ...
- sql server性能调优
转自:https://www.cnblogs.com/woodytu/tag/%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98%E5%9F%B9%E8%AE%AD/defaul ...
随机推荐
- js刷新页面
reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页 ...
- 通过Alexa API获取Alexa排名
我们通会用Alexa的网站(或其它站长工具网站)来栓查我们的网站流量排名,这样就必须去那些网站.实际上,可以通过Alexa XML API 获取网站的Alexa相关的数据(XML格式的),再使用XM ...
- build.gradle中引入jar
只需在 dependencies{}中添加: compile fileTree(include: ['*.jar'], dir: 'libs')
- C#透过PerformanceCounter取得特定Process的CPU使用率
- C语言的本质(31)——C语言与汇编之函数调用的本质
我们一段代码来研究函数调用的过程.首先我们写一段简单的小程序: int sum(int c, int d) { inte = c + d; returne; } int func(int a, int ...
- hdu 5493 Queue(线段树)
Problem Description N people numbered to N are waiting in a bank for service. They all stand in a qu ...
- Unity position和localposition
1. position是根据世界原点为中心 2. localPosition是根据父节点为中心,如果没有父节点,localpositon和position是没有区别的 3.选中一个物体左上角Globa ...
- Unity 制作RPG地图2(自己控制地图上图标)
上一次用Unity摄像机方式实现了地图的制作,现在介绍另一种实现地图的方式: 自己通过代码实现小地图NCP图标的显示和隐藏 制作地图的步骤: 1. 根据游戏人物的3D坐标转换成2D平面坐标,根据距离显 ...
- JSONObject和JSONArray的简单使用(json-lib)
一. jar包 commons-lang.jar commons-beanutils.jar commons-collections.jar commons-logging.jar ezmorph.j ...
- Oracle学习笔记(1)——查询及删除重复数据
1.查找表中多余的重复记录(根据单个字段studentid) select * from table_name where studentid in (select studentid fro ...