简介
在SQL Server中,存储数据的最小单位是页,每一页所能容纳的数据为8060字节,而页的组织方式是通过B树结构(表上没有聚集索引则为堆结构)

在聚集索引B树中,只有叶子节点实际存储数据,而其他根节点和中间节点仅仅用于存放查找叶子节点的数据
每一个叶子节点为一页,
SQL Server向每个页内存储数据的最小单位是表的行(Row)。叶子节点中新插入的行或更新的行使得叶子节点无法容纳当前更新或者插入的行时,分页就产生了.在分页的过程中,就会产生碎片
理解外部碎片
外部碎片指的是由于分页而产生的碎片.比如,我想在现有的聚集索引中插入一行,这行正好导致现有的页空间无法满足容纳新的行。从而导致了分页

新的页是随着数据的增长不断产生的,而聚集索引要求行之间连续,所以很多情况下分页后和原来的页在磁盘上并不连续。这就是所谓的外部碎片
理解内部碎片
我们创建一个表,这个表每个行由int(4字节),char(999字节)和varchar(0字节组成),所以每行为1003个字节,则8行占用空间1003*8=8024字节加上一些内部开销,可以容纳在一个页面中
当我们随意更新某行中的col3字段后,造成页内无法容纳下新的数据,从而造成分页
而当分页时如果新的页和当前页物理上不连续,则还会造成外部碎片
内部碎片和外部碎片对查询性能的影响
1.
由于分页会导致数据在页之间的移动,所以如果插入更新等操作经常需要导致分页,则会大大提升IO消耗,造成性能下降
2.
比页更大的单位是区(Extent).一个区可以容纳8个页.区作为磁盘分配的物理单元.所以当页分割如果跨区后,需要多次切区。需要更多的扫描.因为读取连续数据时会不能预读,从而造成额外的物理读
,增加磁盘IO
对于碎片的解决方法
基本上所有解决办法都是基于对索引的重建和整理,只是方式不同
重建索引固然可以解决碎片的问题.但是重建索引的代价不仅仅是麻烦,还会造成阻塞。影响使用.而对于数据比较少的情况下,重建索引代价并不大。而当索引本身超过百兆的时候。重建索引的时间将会很让人蛋疼
理解填充因子
填充因子为0(0和100表示的是一个概念),则表示页面可以100%使用。所以会遇到前面update或insert时,空间不足导致分页.通过设置填充因子,可以设置页面的使用程度

使用填充因子会减少更新或者插入时的分页次数,但由于需要更多的页,则会对应的损失查找性能
如何设置填充因子的值
T-SQL:
CREATE CLUSTERED INDEX index_name ON table_name(col) WITH (FILLFACTOR = ?)