设为首页 加入收藏

TOP

SQLServer索引维护(1)――如何获取索引使用情况(四)
2015-11-21 01:29:38 来源: 作者: 【 】 浏览:3
Tags:SQLServer 索引 维护 如何 获取 使用 情况
ys.dm_exec_cached_plans的说明中的objtype。Query_plan:使用索引的对象的执行计划,点开后是图形化执行计划。这是语句中最重要的信息之一。Use_counts:对象的执行次数。Plan_handle:在这里它的作用不大。Sql_text:这也是XML片段,它是引用到索引的那部分代码,特别是对动态SQL,我们可以一下子就找到它。

?

?

以上图为例,下面来看看如何使用这些结果。

首先,我们抓重点,看use_counts列,对于那些运行了几个月的系统,这列还是2、3次的,其实没有多大关注必要,除非你要做极限优化。所以我们的切入点是这个列的数据,先挑执行次数最多的来看。注意脚本中已经对use_counts做了排序操作,读者可以按需要修改排序。

找到需要分析的对象之后,点一下最后一列,看看语句情况:注意由于某些存储过程可能多个地方引用或者存储过程本身比较小,所以这个并不是必要步骤,不过看一下大概语句也没坏处,毕竟语句的写法直接影响性能。

如果语句看不出什么问题,再点开执行计划,有些存储过程执行计划的内容很大、很多步骤,所以直接读也不见得是高效。基于本主题,我们希望找到的是索引使用不合理的地方,所以我们还是直接定位索引使用情况。如何定位?查XML。

右键图形化存储过程,选择【显示执行计划XML(X)】,会在新窗口打开执行计划的XML文本。

\

?

第一次打开XML格式的执行计划时可能会被吓一跳,不过不要紧,我们并不是做深入研究,此时只要用普通的查找文本方法找到索引出现的地方即可。使用CTRL+F快捷键,然后把索引名贴进去就可以收缩到索引所在的地方:

\

?

如果你还是读不懂XML执行计划,那就返回图形化里面找:

\

?

把鼠标移到这个图标上即可看到一些我们所需的信息。

按照上面的方式把需要分析的索引分析一遍(分析办法下面会介绍),就可以知道这个索引是否合理,是否可以删除,是否可以合并。

提醒:有些核心表的核心索引可能被几千个对象应用,这些对象主要是动态SQL,只是不同参数而已,在研究参数嗅探时是有价值的,关于这部分另起文章讨论,文章完成后会加上链接。对于使用上面脚本查出来的结果中,若有成百上千行时,一个一个分析显然不合理,此时use_counts又起了一定的作用——找次数足够多的来研究,同时结合sql_text列,找出语句几乎一样仅参数不一样的那些,可以只挑一个研究。一个索引往往就被几个单独的对象应用。如果有大量应用,考虑是否要按业务拆分(所谓的垂直拆分表和业务)。

?

其他信息收集:

下面给出几个收集其他信息的脚本:

缺少索引:

?

--丢失索引
SELECT  user_seeks * avg_total_user_cost *( avg_user_impact *0.01 ) AS [index_advantage] ,
        dbmigs.last_user_seek ,
        dbmid.[statement] AS [Database.Schema.Table],
        dbmid.equality_columns ,
        dbmid.inequality_columns ,
        dbmid.included_columns ,
        dbmigs.unique_compiles ,
        dbmigs.user_seeks ,
        dbmigs.avg_total_user_cost ,
        dbmigs.avg_user_impact
FROM    sys.dm_db_missing_index_group_stats AS dbmigs WITH ( NOLOCK )
        INNER JOIN sys.dm_db_missing_index_groupsAS dbmig WITH ( NOLOCK ) ON dbmigs.group_handle = dbmig.index_group_handle
        INNER JOIN sys.dm_db_missing_index_detailsAS dbmid WITH ( NOLOCK ) ON dbmig.index_handle = dbmid.index_handle
WHERE   dbmid.[database_id] = DB_ID()
ORDER BY index_advantage DESC;

?

索引碎片:

?

--索引上的碎片超过%并且索引体积较大(超过页)的索引。
SELECT  '[' + DB_NAME() + '].[' + OBJECT_SCHEMA_NAME(ddips.[object_id],
                                                    DB_ID())+ '].['
        + OBJECT_NAME(ddips.[object_id], DB_ID()) + ']' AS [statement] ,
        i.[name] AS [index_name] ,
        ddips.[index_type_desc] ,
        ddips.[partition_number] ,
        ddips.[alloc_unit_type_desc],
        ddips.[index_depth] ,
        ddips.[index_level] ,
        CAST(ddips.[avg_fragmentation_in_percent]AS SMALLINT) AS [avg_frag_%] ,
        CAST(ddips.[avg_fragment_size_in_pages]AS SMALLINT) AS [avg_frag_size_in_pages] ,
        ddips.[fragment_count] ,
        ddips.[page_count]
FROM    sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'limited') ddips
        INNER JOIN sys.[indexes] i ON ddips.[object_id] = i.[object_id]
                                      AND ddips.[index_id] = i.[index_id]
WHERE   ddips.[avg_fragmentation_in_percent] > 15
        AND ddips.[page_count] > 500
ORDER BY ddips.[avg_fragmentation_in_percent] ,
        OBJECT_NAME(ddips.[object_id], DB_ID()) ,
        i.[name]


?

注意:检查碎片的前提是表有一定的规模,对于那些小表,即使99%的碎片也不影响什么,还是那句:挑重点。另外本脚本针对碎片率15%的索引做检索,这个比例没有绝对值,但是作为建议,10%~15%以上的碎片率就需要开始重视。

?

?

索引分析:

根据前文所述,我把索引问题主要拆分为三类:索引不合理、索引不足、索引过多。通过上面的信息收集,我们已经得到了足够的信息。

?

索引不合理:

首先我们检查索引定义,如下图:

\

?

从定义中,我们发现几个问题:

1.索引个数很多:加上聚集索引总共有15个!!!!

2.索引命名:这索引命名足够让人奔溃。不多说。

3.看key_cols列中红圈和黄圈部分,我们一般集中注意力在索引的首列,我们可以看到这里有四个索引是可以列入“可合并”的范畴。对于这个列表,我们需要挑出三类索引:

a)第一种是上图所示首

首页 上一页 1 2 3 4 5 6 下一页 尾页 4/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇SQL Server 触发器 下一篇SQL Server中的事务日志管理(7/9)..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: