技术开发 频道

SQL Server索引中的碎片和填充因子

  对于碎片的解决办法

  基本上所有解决办法都是基于对索引的重建和整理,只是方式不同:

  1.删除索引并重建

  这种方式并不好.在删除索引期间,索引不可用.会导致阻塞发生。而对于删除聚集索引,则会导致对应的非聚集索引重建两次(删除时重建,建立时再重建).虽然这种方法并不好,但是对于索引的整理最为有效

  2.使用DROP_EXISTING语句重建索引

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

  3.如前面文章所示,使用ALTER INDEX REBUILD语句重建索引

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

  4.使用ALTER INDEX REORGANIZE

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

  理解填充因子

  重建索引固然可以解决碎片的问题.但是重建索引的代价不仅仅是麻烦,还会造成阻塞。影响使用.而对于数据比较少的情况下,重建索引代价并不大。而当索引本身超过百兆的时候。重建索引的时间将会很让人蛋疼.

  填充因子的作用正是如此。对于默认值来说,填充因子为0(0和100表示的是一个概念),则表示页面可以100%使用。所以会遇到前面update或insert时,空间不足导致分页.通过设置填充因子,可以设置页面的使用程度:

SQL Server索引中的碎片和填充因子(1)

  下面来看一个例子:

  还是上面那个表.我插入31条数据,则占4页:

SQL Server索引中的碎片和填充因子(1)

  通过设置填充因子,页被设置到了5页上:

SQL Server索引中的碎片和填充因子(1)

  这时我再插入一页,不会造成分页:

SQL Server索引中的碎片和填充因子(1)

  上面的概念可以如下图来解释:

SQL Server索引中的碎片和填充因子(1)

  可以看出,使用填充因子会减少更新或者插入时的分页次数,但由于需要更多的页,则会对应的损失查找性能.

  如何设置填充因子的值

  如何设置填充因子的值并没有一个公式或者理念可以准确的设置。使用填充因子虽然可以减少更新或者插入时的分页,但同时因为需要更多的页,所以降低了查询的性能和占用更多的磁盘空间.如何设置这个值进行trade-off需要根据具体的情况来看.

  具体情况要根据对于表的读写比例来看,我这里给出我认为比较合适的值:

  1.当读写比例大于100:1时,不要设置填充因子,100%填充

  2.当写的次数大于读的次数时,设置50%-70%填充

  3.当读写比例位于两者之间时80%-90%填充

  上面的数据仅仅是我的看法,具体设置的数据还要根据具体情况进行测试才能找到最优.

  总结

  本文讲述了SQL SERVER中碎片产生的原理,内部碎片和外部碎片的概念。以及解决碎片的办法和填充因子.在数据库中,往往每一个对于某一方面性能增加的功能也会伴随着另一方面性能的减弱。系统的学习数据库知识,从而根据具体情况进行权衡,是dba和开发人员的必修课.

0
相关文章