讨论了如何使用sys.dm_exec_query_stats动态管理视图(dmv )。本文将以SQL Server 2005为例,讨论如何利用dmv信息来判断tsql的性能优劣。在这篇文章中将继续我有关性能监视问题的讨论,并说明如何使用sys.dm_exec_cached_plans dmv来监视存储过程性能。

  了解dmv统计

  在我开始讨论如何收集存储过程性能的统计数据之前,我们先来回顾一些有关dmv统计的基本知识,如果你已经看过我前面关于dmvs的文章,你应该已经明白SQL Server如何收集和管理dmv信息,你可以跳过该节,从下一节开始看,如果没有,请继续往下读。

  推出SQL Server 2005时,微软介绍了许多被称为dmvs的系统视图,让您可以探测SQL Server 的健康状况,诊断问题,或查看SQL Server实例的运行信息。

  统计数据是在SQL Server运行的时候开始收集的,并且在SQL Server每次启动的时候,统计数据将会被重置。当你删除或者重新创建其组件时,某些dmv的统计数据也可以被重置,例如存储过程和表,而其它的dmv信息在运行dbcc命令时也可以被重置。

  当你使用一个dmv时,你需要紧记SQL Server收集这些信息有多长时间了,以确定这些从dmv返回的数据到底有多少可用性。如果SQL Server只运行了很短的一段时间,你可能不想去使用一些dmv统计数据,因为他们并不是一个能够代表SQL Server实例可能遇到的真实工作负载的样本。另一方面,SQL Server只能维持一定量的信息,有些信息在进行SQL Server性能管理活动的时候可能丢失,所以如果SQL Server已经运行了相当长的一段时间,一些统计数据就有可能已被覆盖。

  因此,任何时候你使用dmv,当你查看从SQL Server 2005的dmvs返回的相关资料时,请务必将以上的观点装在脑海中。只有当你确信从dmvs获得的信息是准确和完整的,你才能变更数据库或者应用程序代码。

  使用次数

  你想知道哪个存储过程执行得最频繁?你可以得到这个结果,但不是如你想像的那样直接去获取它,而只需要把从sys.dm_exec_sql_text表值动态管理函数( DMF )返回的日期加入sys.dm_exec_cached_plans dmv的信息中就可以做到。所以让我通过一些不同的查询来演示一下,以帮助您了解如何使用DMF和DMV获得存储过程的使用次数。

  为了了解sys.dm_exec_cached_plans和sys.dm_exec_sql_text如何工作,请在您的服务器上运行下列代码,并查看输出:

SELECT usecounts, text, dbid, objectid FROM
   sys.dm_exec_cached_plans
cp
   CROSS APPLY
sys.dm_exec_sql_text(cp.plan_handle)
WHERE objtype = 'Proc';

  在这里,我在sys.dm_exec_cached_plans DMV中用CROSS APPLY操作将缓存的计划信息添加到sys.dm_exec_sql_text的输出中。只要DMF从dmv中返回plan_handle值,cross_apply操作将加入这一信息。当在你的机器上运行上述tsql,并查看输出时,你应该会注意到,对于文本列,会有多个行返回同一个值。为什么会发生这种情况?原因是,有时候多个计划存在于同一储存过程的程序缓存中。你可能也察觉到,那个函数看起来就像是扩展存储过程和汇编的CLR存储过程一样。因为某些原因,微软已决定把函数,扩展存储过程,以及CLR存储过程归为一个名为" Proc "的 对象类型 。我认为扩展存储过程和CLR存储过程归类为一个" Proc " 对象类型是有意义的 ,但它将函数也归为"
Proc " 这个对象类型确实是没有意义的,所以,如果只要获得一个用户自定义存储过程的准确使用次数,我把上面的代码做如下修改就可以做到:

SELECT DB_NAME(dbid) AS [DB_NAME], 
       OBJECT_SCHEMA_NAME(objectid,dbid) AS
[SCHEMA_NAME], 
       OBJECT_NAME(objectid,dbid)AS
[OBJECT_NAME], 
       SUM(usecounts) AS [Use_Count], 
       dbid, 
       objectid  
FROM sys.dm_exec_cached_plans cp
   CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle)
WHERE objtype = 'Proc'
  AND UPPER(
-- remove white space first
            REPLACE( 
            
REPLACE(
             
REPLACE(
              
REPLACE(
               
REPLACE(
                
REPLACE(
                 
REPLACE(text,'       ',' '),
                
'       ',' '),
               
'      ',' '),
              
'     ', ' '),
             
'    ',' '),
            
'   ',' '),
            ' 
',' ')
           )
       LIKE '%CREATE PROC%'
GROUP BY dbid, objectid;

  为了帮助您更好地理解本代码,让我解释一下我做的事情。为了消除函数,扩展存储过程和CLR存储过程,我在“text”列中搜索词组“CREATE PROC”,因为你可能在编写创建过程语句的时候,在“CREATE” and “PROC”的关键词之间留了多个空格,我用了一系列替换语句,以清除所有的额外空格,也有可能你编写创建过程语句的时候,使用了混合的大小写,所以我使用UPPER函数将文本统一转换成大写。

  当你运行上面代码的时候,你可能会发现一些db_name列是空的。当dbid值是32767时,就会出现这种情况。因为数据库的ID号与系统数据库,即所谓的资源库是有联系的。这个资源库不是众所周知,但它却是存在于系统中的一个实际数据库,他的确存在,但你在SQL Server Management Studio中却看不到它。在你的数据文件目录下,有一个以字符串“mssqlsystemreource”开始命名的MDF和LDF文件,那就是资源数据库了。该资源库包含了所有编译过的系统存储过程和函数,所以为了彻底地找出所有可能的数据库名称,我已经修改了上面的代码,当dbid等于32767时,填写数据库中的名称列,下面是我的代码,由数据库为所有用户自定义的存储过程确定使用次数:

SELECT CASE when dbid = 32767 
            then
'Resource' 
            else
DB_NAME(dbid) end [DB_NAME], 
       OBJECT_SCHEMA_NAME(objectid,dbid) AS
[SCHEMA_NAME], 
       OBJECT_NAME(objectid,dbid)AS
[OBJECT_NAME], 
       SUM(usecounts) AS [Use_Count], 
       dbid, 
       objectid  
FROM sys.dm_exec_cached_plans cp
   CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle)
WHERE objtype = 'Proc'
  AND UPPER(
-- remove white space first
            REPLACE( 
            
REPLACE(
             
REPLACE(
              
REPLACE(
               
REPLACE(
                
REPLACE(
                 
REPLACE(text,'       ',' '),
                
'       ',' '),
               
'      ',' '),
              
'     ', ' '),
             
'    ',' '),
            
'   ',' '),
            ' 
',' ')
            ) 
       LIKE '%CREATE PROC%'
GROUP BY dbid, objectid;

存储过程中其它与性能相关的查询

  还有其它一些测量存储过程性能的较好的方法。采用使用次数是有意思的,但它并没有告诉你多少资源被使用或该储存过程运行需要花费多长时间,所以,下面我将介绍一个相应的性能监视的TSQL语句,以全面监控你的存储过程性能。

  我喜欢通过一个存储过程中有多少逻辑I/O操作来衡量它的性能。使用逻辑 I / O是一个衡量存储过程执行效率的很好的方法,因为输入/输出通常是所有操作中费时最长的操作,如果你可以减少一定量的I / O操作,通常来说,你的程序性能将会得到大幅改善。这里是一个脚本,可以显示每一个存储过程执行了多少逻辑 I / O操作:

SELECT CASE when dbid = 32767 
            then
'Resource' 
            else
DB_NAME(dbid) end [DB_NAME], 
       OBJECT_SCHEMA_NAME(objectid,dbid) AS
[SCHEMA_NAME], 
       OBJECT_NAME(objectid,dbid)AS
[OBJECT_NAME], 
       SUM(usecounts) AS [Use_Count], 
       SUM(total_logical_reads) AS
[total_logical_reads],
       SUM(total_logical_reads) / SUM(usecounts)
* 1.0 AS [avg_logical_reads],
       dbid, 
       objectid  
FROM sys.dm_exec_cached_plans cp
   CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle)
   JOIN 
   (SELECT SUM(total_logical_reads) AS [total_logical_reads],
          
plan_handle  
      FROM sys.dm_exec_query_stats  
      GROUP BY plan_handle) qs
    ON cp.plan_handle = qs.plan_handle 
WHERE objtype = 'Proc'
  AND UPPER(
-- remove white space first
            REPLACE( 
            
REPLACE(
             
REPLACE(
              
REPLACE(
               
REPLACE(
                
REPLACE(
                 
REPLACE(text,'       ',' '),
                
'       ',' '),
               
'      ',' '),
              
'     ', ' '),
             
'    ',' '),
            
'   ',' '),
            ' 
',' ')
            ) 
       LIKE '%CREATE PROC%'
GROUP BY dbid, objectid
ORDER BY SUM(total_logical_reads) / SUM(usecounts) * 1.0 DESC;

  我使用计算使用次数的查询并把它加入到一个归纳汇总的sys.dm_exec_query_stats dmv中,从而得到每一个存储过程逻辑读的代码。查看avg_logical_reads列,你可以了解到哪些存储过程的效率比较低。

  另一个有意思的事情是衡量一个存储过程执行需要多长时间。所谓执行时间,是指从查询开始到查询结束的时间总量,以秒为单位。有些人也称之为耗费时间,或者说存储过程执行时用户的等待时间。下面是一个查询,用来计算SQL Server 2005中每个存储过程的平均耗费时间:

SELECT CASE when dbid = 32767 
            then
'Resource' 
            else
DB_NAME(dbid) end [DB_NAME], 
       OBJECT_SCHEMA_NAME(objectid,dbid) AS
[SCHEMA_NAME], 
       OBJECT_NAME(objectid,dbid)AS
[OBJECT_NAME], 
       SUM(usecounts) AS
[Use_Count],        
       SUM(total_elapsed_time) AS
[total_elapsed_time],
       SUM(total_elapsed_time) / SUM(usecounts)
* 1.0 AS [avg_elapsed_time],
      
substring(convert(char(23),DATEADD(ms,sum(total_elapsed_time)/1000,0),121),12,23) 
total_elapsed_time_ms,
       dbid, 
       objectid  
FROM sys.dm_exec_cached_plans cp
   CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle)  
   JOIN 
   (SELECT SUM(total_elapsed_time) AS [total_elapsed_time],
          
plan_handle  
      FROM sys.dm_exec_query_stats  
      GROUP BY plan_handle) qs
    ON cp.plan_handle = qs.plan_handle 
WHERE objtype = 'Proc'
  AND UPPER(
-- remove white space first
            REPLACE( 
            
REPLACE(
             
REPLACE(
              
REPLACE(
               
REPLACE(
                
REPLACE(
                 
REPLACE(text,'       ',' '),
                
'       ',' '),
               
'      ',' '),
              
'     ', ' '),
             
'    ',' '),
            
'   ',' '),
            ' 
',' ')
            ) 
       LIKE '%CREATE PROC%'
GROUP BY dbid, objectid
ORDER BY SUM(total_elapsed_time) / SUM(usecounts) * 1.0 DESC;

  结论

  你应该监控你服务器上的所有代码。通过使用这篇文章中代码,你可以找出哪些存储过程使用了大量的资源。在一个开发环境中,当应用正在构建的时候,最适合进行这种监控。你可以使用该技术给你的程序员提供反馈:他们编写的存储过程到底效率如何。给你的程序员一些性能方面的统计数据,可以帮助他们了解怎样才能更好的运行代码,促进高性能设计方式,产生高效率代码。

文章出处:http://database.ctocio.com.cn/tips/161/7810661.shtml

使用sys.dm_exec_cached_plans监控存储过程性能的更多相关文章

  1. [AlwaysOn Availability Groups]监控AG性能

    监控AG性能 AG的性能的性能方面,在关键任务数据库上进行语句级维护性能是很重要的.理解AG如何传输日志到secondary副本对评估RTO和RPO,表明AG是否性能不好. 1. 数据同步步骤 为了评 ...

  2. 【No.2】监控Linux性能25个命令行工具

    接着上一篇博文继续 [No.1]监控Linux性能25个命令行工具 10:mpstat -- 显示每个CPU的占用情况 该命令可以显示每个CPU的占用情况,如果有一个CPU占用率特别高,那么有可能是一 ...

  3. 第七章——DMVs和DMFs(2)——用DMV和DMF监控索引性能

    原文:第七章--DMVs和DMFs(2)--用DMV和DMF监控索引性能 本文继续介绍使用DMO来监控,这次讲述的是监控索引性能.索引是提高查询性能的关键性手段.即使你的表上有合适的索引,你也要时时刻 ...

  4. DBA工具——DMV——通过sys.dm_exec_procedure_stats查看存储过程执行信息

    原文:DBA工具--DMV--通过sys.dm_exec_procedure_stats查看存储过程执行信息 对于DBA来说,经常要手机存储过程的某些信息: 执行了多少次 执行的执行计划如何 执行的平 ...

  5. Dynamic CRM 2013学习笔记(七)追踪、监控及性能优化

    本文将介绍CRM的三个内容追踪.监控及性能优化.追踪是CRM里一个很有用的功能,它能为我们的CRM调试或解决错误.警告提供有价值的信息:我们可以用window的性能监控工具来了解CRM的性能状况:最后 ...

  6. 【No.1】监控Linux性能25个命令行工具

    如果你的Linux服务器突然负载暴增,告警短信快发爆你的手机,如何在最短时间内找出Linux性能问题所在?通过以下命令或者工具可以快速定位 top vmstat lsof tcpdump netsta ...

  7. 优化系统资源ulimit《高性能Linux服务器构建实战:运维监控、性能调优与集群应用》

    优化系统资源ulimit<高性能Linux服务器构建实战:运维监控.性能调优与集群应用> 假设有这样一种情况,一台Linux 主机上同时登录了10个用户,在没有限制系统资源的情况下,这10 ...

  8. 优化Linux内核参数/etc/sysctl.conf sysctl 《高性能Linux服务器构建实战:运维监控、性能调优与集群应用》

    优化Linux内核参数/etc/sysctl.conf  sysctl  <高性能Linux服务器构建实战:运维监控.性能调优与集群应用> http://book.51cto.com/ar ...

  9. 监控Linux性能的18个命令行工具

    监控 Linux 性能的 18 个命令行工具 对于系统和网络管理员来说每天监控和调试Linux系统的性能问题是一项繁重的工作.在IT领域作为一名Linux系统的管理员工作5年后,我逐渐 认识到监控和保 ...

随机推荐

  1. history历史记录在AJAX下出现异常跳转 [解决]

    事情是这样的,在一个历史记录指针应该在[1, 2, 3, 4]的[3]位置的情况下,出现了历史记录指针指向了[4]的情况,而且是在正常后退事件发生之后,(据我所知)没有代码操作的情况发生的. 这是一个 ...

  2. c# WPF——完成一个简单的百度贴吧爬虫客户端

    话不多说先上图 爬取10页大概500个帖子大概10s,500页2w多个帖子大概2min,由此可见性能并不是特别好,但是也没有很差. 好了话不多说,我们来一步一步实现这么个简易的客户端. 1.创建项目 ...

  3. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的

    以下是在论坛中看到的两种解释: (1)如果是要你的代码在编译时发现编译器类型,就判断_cplusplus或_STDC_宏,通常许多编译器还有其他编译标志宏, #ifdef __cplusplus co ...

  4. [Python3] 019 函数:确认过参数,返回对的值

    目录 0. 函数简介 1. 初识函数 2. 函数的参数与返回值 少废话,上例子 3. 查找函数的帮助文档 4. 函数的参数 (1) 参数分类 (2) 结构介绍 1) 普通参数 2) 默认参数 3) 关 ...

  5. [19/05/18-星期六] HTML_form标签

    一.form标签(一) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...

  6. 1 Python 新建项目

    1 新建项目->新建Python文件 2导入package 库文件 3 import 类似using #include 4 写完代码编译 默认debug的对象是第一个创建的py文件,后续写的文件 ...

  7. 探究Javascript模板引擎mustache.js使用方法

    这篇文章主要为大家介绍了Javascript模板引擎mustache.js使用方法,mustache.js是一个简单强大的Javascript模板引擎,使用它可以简化在js代码中的html编写,压缩后 ...

  8. stl(set或map)

    https://nanti.jisuanke.com/t/41384 There are nnn points in an array with index from 111 to nnn, and ...

  9. [Codeforces 1208D]Restore Permutation (树状数组)

    [Codeforces 1208D]Restore Permutation (树状数组) 题面 有一个长度为n的排列a.对于每个元素i,\(s_i\)表示\(\sum_{j=1,a_j<a_i} ...

  10. 入门级,关于下载设置wamp的安装

    将wamp下载下来,分清楚自己电脑是32还是64位,在安装之前,首先确定你电脑里安装了vc++ 的运行库,不然安装wamp后会出现提醒缺少XXX文件,但是注意,在安装vc运行库的时候,请搜索集合包类的 ...