索引维护是数据库日常维护中一项重要的任务,sql server的索引维护其实主要围绕下面三个问题进行展开。
索引过多
索引不足
索引碎片率
本文同样从这3个角度出发,介绍一些实用的日常维护方法和工具。
索引过多是指每个表上面的非聚集索引很多,并且有些非聚集索引很少用到。 过多的索引,会导致增删数据的效率降低,数据库体积变大,索引以及统计信息的维护成本增加等负面影响,建议定期检查类似的索引,每个表上面的索引最好不要超过10个。
通过下面两个dmv,定期检查索引使用率,通过使用率决定是否需要该索引。sys.dm_db_index_operational_stats这个函数可以给出某个索引上面的insert,update和delete的操作情况。sys.dm_db_index_usage_stats这个视图可以给出访问索引的所有方法的操作概览。

上述结果中,可以看到,countryregioncurrency和addresstype表中,有两个索引,没有使用过。 如果多次检查,这两个索引都还是没有使用过的话,建议将其删除。
索引不足是指,要么缺少索引,要么有索引,但是没有覆盖所需的列,查询效果不好。 后者其实也可以归纳到索引不合适中。那么我们来看下,如何才能找到缺失的索引。
sql server提供下面4个dmv以供查询missing index的情况。sql server重启后,系统视图中的内容就会更新,需要定期的将该信息保存下来。
下面语句,在每个库上面执行下面的查询,查看推荐建立的索引,包括创建语句。不过在创建索引前,需要综合考量表中已有的索引,是否有可以合并的情况。
创建index时,推荐按照下述顺序进行。
将相等数据行列在最前
将不相等的数据行列在相等的数据行后
将include数据行列在create index语句的include子句中
若要决定相等数据行的顺序,依据选择性排列这些数据行,将选择性最高的数据行排在最前
新增、删除和修改数据时,数据库会自动维护索引。但时间长了之后,这些操作会造成数据不连续。这会对查找性能产生影响。
首先,观察索引碎片的严重程度。
内部不连续(internal fragmentation):数据页中有很多空闲空间;
外部不连续(external fragmentation):
硬盘中摆放的分页或区不连续,也就是数据表或索引散落在多个范围中,以及存放数据表或者索引的页不是按照实例连续存放的。
逻辑数据顺序和实例在硬盘中的顺序不同。
1. 用dbcc showcontig观察数据不连续
红框中的参数反应外部不连续状况。索引idcreditcard总共用了43页,6个区,光标扫描区时转换了5次,每个区平均7.2页,扫描密度100%,逻辑扫描片段为0,区扫描碎片率33.33% (=读取时跳过的区数/总共使用的区数)。
最后两个参数avg. bytes free per page和avg. page density (full)则反应的是内部不连续的情况,平均每页空闲字节数越大,说明内部不连续越严重。
可以通过定义一个临时表来观察数据不连续情况。
查看department表的索引不连续情况:
查看数据库中所有索引的碎片情况
3. 根据数据片段状况来判断是否要重组或者重建索引。
当索引碎片大于5%,小于等于30%时,建议reorganize该索引;当索引碎片率大于30%时,建议rebuild该索引。rebuild index比较耗性能,建议在非工作时间进行,同时,建议使用online 的方式来rebuild index,以减少锁的申请量。
重组索引:
重建索引:
维护计划重建索引