设为首页 加入收藏

TOP

SQLServer索引维护(1)――如何获取索引使用情况(三)
2015-11-21 01:29:38 来源: 作者: 【 】 浏览:5
Tags:SQLServer 索引 维护 如何 获取 使用 情况
ND i.index_id = ddius.index_id WHERE OBJECTPROPERTY(ddius.[object_id], 'IsUserTable') = 1 AND ddius.database_id = DB_ID() AND OBJECT_NAME(ddius.[object_id])='表名' AND i.index_id > 1 --非聚集索引 ORDER BY [Difference] DESC , [Total Writes]DESC , [Total Reads]ASC;

?

我们这里主要关注非聚集索引,因为绝大部分情况下,聚集索引是主键,在系统运行了一段时间后,你能修改主键的可能已经大大降低,并且主键一般问题不大。下面是语句执行的大概样子:

\

?

得到了这些信息之后,就开始做初步分析,对于大部分系统而言,读操作远大于写操作,所以如果你的系统也是类似的,那么可以选出上图中【Total Reads】远小于【Total Writes】的那些索引进行优先分析对象,如上图的第五个索引。

?

某个索引被使用的具体情况:

再次说明,很多方法可以实现这种分析,在不需要深入研究的情况下,够用就好。本人通过改写国外大牛的一个关于查找“并行执行语句”的脚本,实现获取某个索引自实例启动依赖被使用的具体情况。原脚本如下:

?

--执行计划中使用了并行操作的语句:
SET TRANSACTION ISOLATIONLEVEL READ UNCOMMITTED;
WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT COALESCE(DB_NAME(p.dbid)
    , p.query_plan.value('(//RelOp/OutputList/ColumnReference/@Database)[1]','nvarchar(128)'))
     AS database_name
  ,DB_NAME(p.dbid) + '.' + OBJECT_SCHEMA_NAME(p.objectid, p.dbid)
    + '.' + OBJECT_NAME(p.objectid, p.dbid) AS object_name
  ,cp.objtype
  ,p.query_plan
  ,cp.UseCounts AS use_counts
  ,cp.plan_handle
  ,CAST('
  ' AS XML) AS sql_text
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) p
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS q
WHERE cp.cacheobjtype = 'Compiled Plan'
AND p.query_plan.exist('//RelOp[@Parallel = "1"]') = 1
ORDER BY COALESCE(DB_NAME(p.dbid), p.query_plan.value('(//RelOp/OutputList/ColumnReference/@
Database)[1]','nvarchar(128)')), UseCountsDESC

?

下面是本人改写后的脚本:

?

--获取某个索引被使用的情况
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT COALESCE(DB_NAME(p.dbid)
    ,p.query_plan.value('(//RelOp/OutputList/ColumnReference/@Database)[1]','nvarchar(128)'))
     ASdatabase_name
  ,DB_NAME(p.dbid) + '.' + OBJECT_SCHEMA_NAME(p.objectid, p.dbid)
    +'.' + OBJECT_NAME(p.objectid, p.dbid) AS OBJECT_NAME,
    cast ('索引名' as varchar(64)) AS IndexName
  ,cp.objtype
  ,p.query_plan
  ,cp.UseCounts AS use_counts
  ,cp.plan_handle
  ,CAST('
  ' AS XML) AS sql_text INTO xxx.xxx.xxx表
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) p
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS q
WHERE cp.cacheobjtype = 'Compiled Plan'
AND p.query_plan.exist('//Object[@Index = "[索引名]"]') = 1
ORDER BY UseCounts DESC,COALESCE(DB_NAME(p.dbid), p.query_plan.value('(//RelOp/OutputList/ColumnReference/@
Database)[1]','nvarchar(128)'))


?

脚本有两个注意的地方:

1.需要手动替换语句中的“索引名”三个字,共两处地方。另外要注意的是,这个语句查询的是XML格式的执行计划,XML是大小写区分的,所以要严格按照索引名(在SSMS中查到的名字)来替换,否则查询不出来。另外针对索引名,本系统就出现过不同的表使用了相同的索引名(如index1),这种极其乱来的命名规则应该避免。这种情况也导致了你分析的索引可能是另外一个表的,所以需要再次检查。

2.脚本中有INTO xxx.xxx.xxx表的部分。这个是本人的监控习惯,在同一个服务器上,若有空间和条件,建议创建一个独立的数据库(简单模式即可),存储所有你感兴趣的数据库运维和性能信息,以便后续之用。这个如果不需要存储,记得注释掉。

?

下面是脚本结果的示例:

\

?

接上图

\

?

现在来解释一下这个结果:

?

Database_name:指使用这个索引的对象(如存储过程)所在的数据库,本 系统存在跨库操作的行为,所以一个索引可能被多个数据库的对象使用。这个可以用于找到对象所在的数据库,如果有必要可以对这个数据库做进一步分析,如这个数据库的配置情况等。OBJECT_NAME:这个是使用索引的对象名,如果是数据库内存储的对象(如存储过程、函数、视图等),这里会有结果,如果是动态SQL,此处为NULL。IndexName:索引名字,一般仅用来后续统计之用。Objtype:使用索引的对象类型:Proc为存储过程,Prepared为预定义语句,详细类型说明可以查看联机丛书关于s
首页 上一页 1 2 3 4 5 6 下一页 尾页 3/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇SQL Server 触发器 下一篇SQL Server中的事务日志管理(7/9)..

评论

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