2024年4月15日发(作者:农雅昶)
SQLServer索引碎片和解决方法
毫无疑问,给表添加索引是有好处的,你要做的大部分工作就是维护索引,在数
据更改期间索引可能产生碎片,所以一些维护是必要的。碎片可能是你查询产生性能问题
的来源。
那么到底什么是索引碎片呢?索引碎片实际上有2种形式:外部碎片和内部碎片。不
管哪种碎片基本上都会影响索引内页的使用。这也许是因为页的逻辑顺序错误(即外部碎
片)或每页存储的数据量少于数据页的容量(内部错误)。无论索引产生了哪种类型的碎片,
你都会因为它而面临查询的性能问题。
外部碎片
当索引页不在逻辑顺序上时就会产生外部碎片。索引创建时,索引键按照逻辑顺序放
在一组索引页上。当新数据插入索引时,新的键可能放在存在的键之间。为了让新的键按
照正确的顺序插入,可能会创建新的索引页来存储需要移动的那些存在的键。这些新的索
引页通常物理上不会和那些被移动的键原来所在的页相邻。创建新页的过程会引起索引页
偏离逻辑顺序。
下面的例子将比实际的言论更加清晰的解释这个概念。
假定在任何另外的数据插入你的表之前存在索引上的结构如下
(注:下面图片里应该是7和8,原文里是6和8):
INSERT语句往索引里添加新的数据,假定添加的是5。INSERT将引起新页创建,为
了给5在原来的页上留出空间,7和8被移到了新页上。这个创建将引起索引页偏离逻辑
顺序。
在有特定搜索或者返回无序结果集的查询的情况下,偏离顺序的索引页不会引起问题。
对于返回有序结果集的查询,搜索那些无序的索引页需要进行额外的处理。有序结果集的
例子如查询返回4到10之间的记录。为了返回7和8,查询不得不进行额外的页切换。
虽然一个额外的页切换在一个长时间运行里是无关紧要的,然而想象一下一个有好几百页
偏离顺序的非常大的表的情形。
内部碎片
当索引页没有用到最大量时就产生了内部碎片。虽然在一个有频繁数据插入的应用程
序里这也许有帮助,然而设置一个fill factor(填充因子)会在索引页上留下空间,服务器
内部碎片会导致索引尺寸增加,从而在返回需要的数据时要执行额外的读操作。这些额外
的读操作会降低查询的性能。
怎样确定索引是否有碎片?
2024年4月15日发(作者:农雅昶)
SQLServer索引碎片和解决方法
毫无疑问,给表添加索引是有好处的,你要做的大部分工作就是维护索引,在数
据更改期间索引可能产生碎片,所以一些维护是必要的。碎片可能是你查询产生性能问题
的来源。
那么到底什么是索引碎片呢?索引碎片实际上有2种形式:外部碎片和内部碎片。不
管哪种碎片基本上都会影响索引内页的使用。这也许是因为页的逻辑顺序错误(即外部碎
片)或每页存储的数据量少于数据页的容量(内部错误)。无论索引产生了哪种类型的碎片,
你都会因为它而面临查询的性能问题。
外部碎片
当索引页不在逻辑顺序上时就会产生外部碎片。索引创建时,索引键按照逻辑顺序放
在一组索引页上。当新数据插入索引时,新的键可能放在存在的键之间。为了让新的键按
照正确的顺序插入,可能会创建新的索引页来存储需要移动的那些存在的键。这些新的索
引页通常物理上不会和那些被移动的键原来所在的页相邻。创建新页的过程会引起索引页
偏离逻辑顺序。
下面的例子将比实际的言论更加清晰的解释这个概念。
假定在任何另外的数据插入你的表之前存在索引上的结构如下
(注:下面图片里应该是7和8,原文里是6和8):
INSERT语句往索引里添加新的数据,假定添加的是5。INSERT将引起新页创建,为
了给5在原来的页上留出空间,7和8被移到了新页上。这个创建将引起索引页偏离逻辑
顺序。
在有特定搜索或者返回无序结果集的查询的情况下,偏离顺序的索引页不会引起问题。
对于返回有序结果集的查询,搜索那些无序的索引页需要进行额外的处理。有序结果集的
例子如查询返回4到10之间的记录。为了返回7和8,查询不得不进行额外的页切换。
虽然一个额外的页切换在一个长时间运行里是无关紧要的,然而想象一下一个有好几百页
偏离顺序的非常大的表的情形。
内部碎片
当索引页没有用到最大量时就产生了内部碎片。虽然在一个有频繁数据插入的应用程
序里这也许有帮助,然而设置一个fill factor(填充因子)会在索引页上留下空间,服务器
内部碎片会导致索引尺寸增加,从而在返回需要的数据时要执行额外的读操作。这些额外
的读操作会降低查询的性能。
怎样确定索引是否有碎片?