使用Profiler找出低效的查询
2009-12-04 07:03:24| 分类: sql server调优 |字号 订阅
监控列表 | 你的答案 |
你分辨过所有长时间运行的查询吗? |
|
对这些查询你区分优先次序了吗? | |
你重新查看过上面区分优先次序的查询的执行计划了吗? |
|
在上表输入你的结果
第一步是分辨出长时间运行的查询
到SQLServer性能监控的这一步止,你应该已经能分辨出所有容易纠正的性能问题了。现在是着手处理更差的查询(包括存储过程)的时候了,那些比预期运行时间更长的占用大量SQLServer共享资源的查询和存储过程。
运行慢的查询执行要花费太长的时间。那么究竟多长才算长呢?这得由你决定。通常说来,我用5秒作为一个坎儿。换句话说,任何一个查询运行5秒或更少通常就算足够快了,而查询超过5秒就算长了。这是一个你不得不做出的武断的决定。在我工作的公司,报表开发人员要写大量的和我有不同标准的征对数据库的查询。他们考虑的时长为30秒。所以,第一步就是决定多长时间的查询才算长,然后在你的服务器性能监控期间使用这个作为你的标准。
我们不能无限制的调优查询。我们所能做的就是分辨出那些需要更多工作的查询,然后征对它们进行调优。如果有时间的话,为了全面提升SQLServer的性能,可以着眼于那些稍慢但仍然讨厌的查询。记住有些时候,无论你怎么努力调优一个特殊的查询,可能仅有一点或根本没有性能上的改善。
开始之前
对于这部分性能监控,你将使用SQLServer自带的事件探查器。本篇文章仅着眼于怎样进行性能监控,而不是工具的使用,所以假定你知道怎样使用事件探查器。如果你以前没有用过它,查看BOL以获得一些基本的帮助。
在你使用事件探查器捕捉你的SQLServer查询活动之前,记住下面的:
- 不要在你要监控的同一台服务器上运行事件探查器,这对服务器性能有一个明显的影响。相反,在另一个服务器或工作站上运行,然后在那儿收集数据。
- 当运行事件探查器时,不要选择比需要收集更多的数据。你收集的数据越多,用来收集它们而使用的资源就越多,这会降低性能。仅仅选择那些你真正需要的事件和数据列。我的建议是所收集的真正的要简短。
- 在一段典型的服务器运行时间内收集数据,即典型的3-4小时的时间。这也可以改变,依赖于你服务器繁忙的程度。如果你没有这样的时间,你可以通过一个典型的生产日的几个不同时间段来收集你需要的所有数据。
收集什么数据
事件探查器允许你指定哪些事件需要捕捉,那些事件的哪些数据列需要捕捉。另外,你可以使用筛选来减少数据而仅要哪些分析需要的社会局。下面是我的建议:
要捕捉的事件
- Stored Procedures--RPC:Completed
- TSQL--SQL:BatchCompleted
需要捕捉的数据列
- Duration (数据需要通过duration来分组)
- Event Class
- DatabaseID (如果服务器上有多个数据库的话)
- TextData
- CPU
- Writes
- Reads
- StartTime (可选的)
- EndTime (可选的)
- ApplicationName (可选的)
- NTUserName (可选的)
- LoginName (可选的)
- SPID
用于筛选
- Duration > 5000 毫秒 (5秒)
- 不要收集系统事件
- 通过单独的数据库ID而不是一次所有的数据库都收集数据
- 其他适当的筛选
收集数据
依赖于使用的筛选、运行事件探查器收集数据的时间、服务器繁忙程度,你可以收集大量的数据行。虽然你有几个选择,我建议你配置事件探查器保存数据到本地计算机的文件上(而不是你跟踪的服务器上)并且不设置文件的最大尺寸,相反,让文件按需增长。你要查看文件的增长量,万一它无法控制。大多数情况下,如果你使用了正确的筛选,文件大小会便于处理的。我建议使用一个大的文件因为如果你那样做的话很容易分辨出长时间运行的查询。
正如前面所述,在一个典型的生产期间收集你的跟踪文件,大约3-4小时为一期限。当收集数据后,可使用duration来分类,运行时间最长的查询出现在跟踪窗口的底部。当你收集数据的时候有兴趣的话可以看一会儿窗口。如果你喜欢,可以配置在适当的时候自动关闭事件探查器,也可以手动关闭。
一旦时间到跟踪停止了, 事件探查器的跟踪现在存在本地计算机的内存和磁盘上。现在你准备去分辨那些长时间运行的查询了。
分析数据
我猜你已经能分辨出所有在跟踪收集期间运行的超过你指定的duration的所有查询,不管是不是。所以如果你指定duration为5秒,那么你将只看到那些运行超过5秒的查询。根据定义,你捕捉的所有查询都需要调优。"什么!但捕捉到了500多个查询啊! 那可是一项大工程!"那并不是你想象的那么糟。大多数情况下,你捕捉的很多查询是重复的。换句话说,你可能在你的跟踪里一再地捕捉了同样的查询。所以,那些500多个捕捉到的查询也许仅仅只有10个或50个或100不重复的查询。另一方面,也许捕捉到的只是少数的查询,如果你够幸运的话。
无论是少数查询还是大量运行慢的查询,你接下来的工作是首先决定哪一个查询对你的分析和调优来说是最重要的。这需要你设置优先级,因为你可能没有足够的时间去分析所有的查询。
为了设置这些长时间运行的查询的优先级,你可能首先要着眼于那些运行最长的查询。但当你这么做时,要记住每个查询运行的频率。
例如,如果你指定一个特定的查询仅仅是为了生成报表而一个月只运行一次(碰巧在它运行的时候你捕捉到了),这个查询运行花了60秒,它可能没有那些运行花了10秒但1分钟运行了10次的查询的优先级高。换句话说,你需要平衡查询运行的时长和频率。谨记这一条:你需要分辨并设置那些花费最多SQLServer物理资源的查询的优先级。一旦你做完这件事,就可以准备分析和调优了。
通过查看执行计划分析查询
为了分析你捕捉到的已经设置优先级的查询,你需要把代码移到查询分析器里以便能查看执行计划,分析查询。本篇文章着重在监控,而不是分析,我们不会在这里花费时间去向你展示怎样分析特定的查询。这本身是一个很大的课题,将在其他地方做介绍。
为了分析你怎样移到代码到查询分析器里依赖于代码。如果你捕捉到的代码是TSQL,你可以剪切,然后直接在查询分析器里粘贴。但如果代码是在存储过程里,你不得不稍微多做一点工作,因为事件探查器不会显示存储过程里的代码,而仅显示存储过程的名称,包括传给它的所有参数。这样,为了在查询分析器里分析查询,你必须考虑到存储过程里,将代码复制粘贴到查询分析器里。然后,假定那儿也有一些参数了,你不得不手工更改代码以便它能带着参数运行而被事件探查器捕获。
现在耗时的杂事开始了,分析每一个查询的执行计划看看有没有能改善性能的查询需要调优。但是因为你已经分辨和设置这些查询的优先级可,所以你的时间将更有效率。