起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 381|回复: 4

【分享】关于SQL Server性能分析参数**

[复制链接]
发表于 2007-5-8 15:44:10 | 显示全部楼层 |阅读模式
以下内容来源于 http://searchdatabase.techtarget.com.cn/tips/318/1889818.shtml
============================
SQL Server计数器

作者: Barrie Sosinsky,  出处:, 责任编辑: 丁一凡, 2004-12-17 09:38

  性能监视器(Performance Monitor)是你能用于监控SQL服务器的性能(其他两是Profiler 和Enterprise Manager)的3 个工具之一。 由于具有超过156个独立的计数器和创建你自己拥有的计数器的能力(在SQL Server Books Online里有所描述),你工作时会涉及到一系列的工具。Windows 服务器版操作系统为你提供了可供分析的数百个计数器。有一个词汇"信息过载(information overload)"会出现在你脑海里。然而,有些计数器比其它的要有价值得多,而且你特定的设置和故障诊断会指导你使用哪一系列的计数器。
  你可以从菜单命令处找到性能监视器,也可以从Profiler工具条处找到它。在7.0版本中,默认安装并监控了6个计数器:超高速缓冲器命中率,页面读取,页面写入,SQL每秒编译次数,总服务器内存,以及用户连接。这些根据你所使用的SQL Server的版本的不同而有所不同,因为在6.5版中,默认市5个计数器:超高速缓冲器命中率,三个I/O计数器(每秒页面读取,每秒单个页面写入,以及每秒处理次数),还有一个用户连接。这些计数器集测量类似的量度,但具有略为不同的含义和解释。
  一次测量一个计数器是一个好办法。最重要的计数器可能是:磁盘I/O,处理器,内存,用户连接,以及网络。这些是数据库性能的主要瓶颈(通常情况下),你可以对它们进行适当的修正。你会发现性能监视器收集比你所需更多的数据,通常情况是这样;或者,你可能发现你想要分析的性能特点在下一次数据扫描之前已经从图表中删除了。使用选项 | 图表命令调整更新频率,以便你能够更好地查看你的结果的重要特征。
  当你在排除故障或者诊断问题时,你会发现你想要增加更多的计数器。可以通过“编辑 | 添加到图表”命令或者那个工具栏上的Plus图标来把计数器添加到性能监视器。在选择j计数器时你还需要注意你所添加的特定寄存器的各种实例。例如,某些实例是针对数据库的,而有些实例不是。比如,SQL Server7.0的有22个计数器,表示70个实例。
  要知道很多计数器将导致系统性能的下降,所以请不要永久安装一个能够使你的数据库操作变慢的计数器。你还会发现,有些计数器只要性能监视器打开就一直运行到你退出工具并关闭性能监视器为止。
  现在让我们更进一步的看看这个重要的检测和最优化工具。
  有一些明显的瓶颈值得查找。如果你使用物理磁盘:% Disk Time或者物理磁盘:Current Disk Queue Length(所有实例)来测量磁盘I/O,你应该保持磁盘时间计数器的值在2.0以下。超过3.0的一个当今的磁盘队列长度也表明你可能有一个磁盘I/O 瓶颈。 立刻测量两个计数器看看它们是否有相互关联是一种好想法; 并且你能点击踪迹高亮显示它并且使用Ctrl+H来高亮显示被选择的踪迹。 第二个瓶颈是处理器, 并且你应该你系统的每台处理器打开处理器的实例:% Processor Time Counter(处理器时间计数器)。 你寻找两个值:处理器总体活动和处理器负载如何被平衡。 任何一个持续负载超过百分之80的处理器都需要更新。
  4 个内存计数器: SQL Server: 缓冲管理: 高速缓存命中率和迟钝写入,存储器: 页面每秒出错和页面文件:% Usage(使用率)都值得监控。 任何低于80%的高速缓存命中率可能指示你需要更多的存储器储存缓冲的数据, 如同过多的页面出错或者页面文件使用率一样。迟钝写入应该通常是0,正的值注明页面正在被写入磁盘。 所有这些计数器都是足够的内存的表征。
  不要忘记也看看你的用户连接和网络性能的数量。有用的连接计数器是: SQL Server: 一般的统计:用户连接和SQL Server:内存管理:连接内存(KB)。 应该将这些计数器与CPU 使用协同分析,每秒注册次数,和允许的工作区内存,和所有与建立和保持你的连接通路有关。
如果你正测量磁盘性能并收集一套统计数据,然后你需要打开diskperf命令 - 制止性能被影响。命令快捷方式diskperf-y 将开始这种服务,或者可以打开设备控制面板并且在那里把它打开。 为了让性能监视器接受新设置,你可能必须重新启动你的系统。你把你的设置保存成一个PMC 文件,这是一个仅限于你的SQL服务器的实例的一个文件。性能监视器也能保留日志文件,在PerfMon的在线帮助中有所描述。
  PerfMon被创建为一件开发者的工具,同时供最终用户使用。你也能够创建你自己的计数器。 可以检查SQL Server Online看看这是怎么实现的。例如,你能使用一个定制的计数器来监控从一个特定服务器进入的业务量,以及其它几乎所有你可以想象到的特性。
回复

使用道具 举报

 楼主| 发表于 2007-5-8 15:44:46 | 显示全部楼层
以下内容来自 http://www.80o.com/web/station/datas/sqlserver/5659783134.html
=================================
SQL Server性能分析参数


时间:2006年10月15日  【字体:大 中 小】
当您怀疑计算机硬件是影响SQL Server运行性能的主要原因时,可以通过SQL Server Performance Monitor监视相应硬件的负载,以证实您的猜测并找出系统瓶颈。下文将介绍一些常用的分析对象及其参数。

Memory: Page Faults / sec

  如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。

Process: Working Set

  SQL Server的该参数应该非常接近分配给SQL Server的内存值。在SQL Server设定中,如果将"set working set size"置为0, 则Windows NT会决定SQL Server的工作集的大小。如果将"set working set size"置为1,则强制工作集大小为SQLServer的分配内存大小。一般情况下,最好不要改变"set working set size"的缺省值。

Process:%Processor Time

  如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。

Processor:%Privileged Time

  如果该参数值和"hysical Disk"参数值一直很高,表明I/O有问题。可考虑更换更快的硬盘系统。另外设置Tempdb in RAM,减低"max async IO","max lazy writer IO"等措施都会降低该值。

Processor:%User Time
  
  表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。

Physical Disk:Avg.Disk Queue Length

  该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。
  注意:一个Raid Disk实际有多个磁盘。

SQLServer:Cache Hit Ratio

该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。


转自:动态网站制作指南 | www.knowsky.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-5-8 15:54:02 | 显示全部楼层
以下内容来自 http://www.sql-server-performanc ... ters_sql_server.asp
=====================
Tips for Using SQL Server Performance Monitor Counters

--------------------------------------------------------------------------------



One cause of excess I/O on a SQL Server is page splitting. Page splitting occurs when an index or data page becomes full, and then is split between the current page and a newly allocated page. While occasional page splitting is normal, excess page splitting can cause excessive disk I/O and contribute to slow performance.

If you want to find out if your SQL Server is experiencing a large number of page splits, monitor the SQL Server Access Methods object: Page Splits/sec. If you find out that the number of page splits is high, consider increasing the fill factor of your indexes. An increased fill factor helps to reduce page splits because there is more room in data pages before it fills up and a page split has to occur.

What is a high Page Splits/sec? There is no simple answer, as it somewhat depends on your system's I/O subsystem. But if you are having disk I/O performance problems on a regular basis, and this counter is over 100 on a regular basis, then you might want to experiment with increasing the fill factor to see if it helps or not. [6.5, 7.0, 2000] Updated 9-4-2006

*****

If you want to see how much physical RAM is devoted to SQL Server's data cache, monitor the SQL Server Buffer Manager Object: Cache Size (pages). This number is presented in pages, so you will have to take this number and multiply it by 8K (8,192) to determine the amount of RAM in K that is being used.

Generally, this number should be close to the total amount of RAM in the server, less the RAM used by NT, SQL Server, and any utilities you have running on the server.

If the amount of RAM devoted to the data cache is much smaller than you would expect, then you need to do some investigating to find out why. Perhaps you aren't allowing SQL Server to dynamically allocate RAM, and instead have accidentally specified that SQL Server use less RAM that it should have access to for optimal performance. Whatever the cause, you need to find a solution, as the amount of data cache available to SQL Server can significantly affect SQL Server's performance.

In the real world, I don't spend much time looking at this counter, as there are other counters that do a better job of letting you know if SQL Server is memory starved or not. [6.5, 7.0, 2000] Updated 9-4-2006

*****

To get a feel of how busy SQL Server is, monitor the SQLServer: SQL Statistics: Batch Requests/Sec counter. This counter measures the number of batch requests that SQL Server receives per second, and generally follows in step to how busy your server's CPUs are. Generally speaking, over 1000 batch requests per second indicates a very busy SQL Server, and could mean that if you are not already experiencing a CPU bottleneck, that you may very well soon. Of course, this is a relative number, and the bigger your hardware, the more batch requests per second SQL Server can handle.

From a network bottleneck approach, a typical 100 Mbs network card is only able to handle about 3000 batch requests per second. If you have a server that is this busy, you may need to have two or more network cards, or go to a 1 Gbs network card.

Some DBAs use the SQLServer: Databases: Transaction/Sec: _Total to measure total SQL Server activity, but this is not a good idea. Transaction/Sec only measures activity that is inside a transaction, not all activity, producing skewed results. Instead, always use the SQLServer: SQL Statistics: Batch Requests/Sec counter, which measures all SQL Server activity. [7.0, 2000] Updated 9-4-2006

*****

SQL compilations of Transact-SQL code is a normal part of SQL Server's operation. But because compilations chew up CPU and other resources, SQL attempts to reuse as many execution plans in cache as possible (execution plans are created when compilations occur). The more execution plans are reused, the less overhead there is on the server, and the faster overall performance there is.

To find out how many compilations SQL Server is doing, you can monitor the SQLServer: SQL Statistics: SQL Compilations/Sec counter. As you would expect, this measures how many compilations are performed by SQL Server per second.

Generally speaking, if this figure is over 100 compilations per second, then you may be experiencing unnecessary compilation overhead. A high number such as this might indicate that you server is just very busy, or it could mean that unnecessary compilations are being performed. For example, compilations can be forced by SQL Server if object schema changes, if previously parallelized execution plans have to run serially, if statistics are recomputed, or if a number of other things occur. In some cases, you have the power to reduce the number of unnecessary compilations. See this page for tips on how to do this.

If you find that your server is performing over 100 compilations per second, you should take the time to investigate if the cause of this is something that you can control. Too many compilations will hurt your SQL Server's performance. [7.0, 2000] Updated 9-4-2006

*****

The SQLServer: Databases: Log Flushes/sec counter measures the number of log flushes per second. This can be measured on a per database level, or for all databases on a SQL Server.

So exactly what is a log flush? The best way to describe it is to provide an example. Let's say that you want to start a transaction that has 10 INSERTs in it. When the transaction begins, and the first INSERT is made, and new data is inserted into data pages, essentially two things happen at the same time. The data page in the buffer cache is updated with the newly INSERTed row of data, and the appropriate data for the log file is written to the log cache for this single INSERT. This continues to happen until the transaction is complete. At this time, the data for this transaction from the log cache is immediately written to the log file, but the data in the buffer cache stays there until the next checkpoint process runs, which at that time the database is updated with the newly INSERTed rows.

You may have never heard of the log cache, which is a place in memory that SQL Server records data to be written to the log file. The purpose of the log cache is very important, as it is used to roll back a transaction before it is committed, if the circumstances call for it. But once a transaction is complete (and no longer can be rolled back), this log cache is immediately flushed to the physical log file. This is a normal procedure. Keep in mind that SELECT queries that don't modify data don't create transactions and don't produce log flushes.

Essentially, a log flush occurs when data is written from the log cache to the physical log file. So in essence, a log flush occurs every time after a transaction is complete, and the number of log flushes that occur are related to the number of transactions performed by SQL Server. And as you might expect, the size of a log flush (how much data is written from the log cache to disk) varies depending on the transaction. So how can this information help us?

Let's say that we know we have a disk I/O bottleneck, but we are not sure what is causing it. One way to trouble-shoot the disk I/O bottleneck is to capture the Log Flushes/sec counter data and see how busy this mechanism is. As you might expect, if your server experiences lots of transactions, it will also experience a lot of log flushes, so the value you see for this counter can vary from server to server, depending on how busy it is with action-type queries that create transactions. What you want to do with this information is to try to identify situations where the number of log flushes per seconds seems to be significantly higher than the expected number of transactions that you think should be running on a server.

For example, let's say that you have a daily process that INSERTs 1,000,000 rows into a table. There are several different ways that these rows could be inserted. First, each row could be inserted separately, each INSERT wrapped inside a single transaction. Second, all of the INSERTS could be performed within a single transaction. And last, the INSERTs might be divided into multiple transactions, somewhere between 1 and 1,000,000. Each of these options is different and has a significantly different effect on SQL Server, and the number of log flushes per second. In addition, it's easy to make a mistake and assume that this process you are running is a single transaction, even though it might not be. Most people tend to think of a single process as a single transaction.

In the first case, if 1,000,000 rows are INSERTed with 1,000,000 transactions, there will also be 1,000,000 log flushes. But in the second case, 1,000,000 rows will be inserted within a single transaction, and there will only be one log flush. And in the third case, the number of log flushes will equal the number of transactions. Obviously, the size of the log flush will be bigger with 1,000,000 transactions than with 1 transaction, but for the most part, this is not important from a performance standpoint as described here.

So which option is best? In all cases, you will still be producing a lot of disk I/O. There is no way to get around this if you deal with 1,000,000 rows. But by using one or just a few transactions, you reduce the number of log flushes significantly, and disk I/O is reduced significantly, which helps to reduce the I/O bottleneck, boosting performance.

So we have learned two key things here. First, that you want to reduce log flushes as much as you can, and one key way to do this is to reduce the number of transaction occurring on your server. [7.0, 2000] Updated 9-4-2006

*****

Since the number of users using SQL Server affects its performance, you may want to keep an eye on the SQL Server General Statistics Object: User Connections. This shows the number of user connections, not the number of users, that are currently connected to SQL Server.

When interpreting this number, keep in mind that a single user can have multiple connections open, and also that multiple people can share a single user connection. Don't make the assumption that this number represents actual users. Instead, use it as a relative measure of how "busy" the server is. Watch the number over time to get a feel if your server is being used more, or being used less. [6.5, 7.0, 2000] Updated 6-12-2006

*****

If your databases are suffering from deadlocks, you can track then by using the SQL Server Locks Object: Number of Deadlocks/sec. But unless this number is relatively high, you want see much here because the measure is by second, and it takes quite a few deadlocks to be noticeable.

But still, it is worth checking out if you are having a deadlock problem. Better yet, use the Profiler's ability to track deadlocks. It will provide you with more detailed information. What you might consider doing is to use the Number of Deadlocks/sec counter on a regular basis to get the "big" picture, and if you discover deadlock problems with this counter, then use the Profiler to "drill" down on the problem for a more detailed analysis. [6.5, 7.0, 2000] Updated 6-12-2006

*****

If your users are complaining that they have to wait for their transactions to complete, you may want to find out if object locking on the server is contributing to this problem. To do this, use the SQL Server Locks Object: Average Wait Time (ms). You can use this counter to measure the average wait time of a variety of locks, including: database, extent, Key, Page, RID, and table.

As the DBA, you have to decide what an acceptable average wait time is. One way to do this is to watch this counter over time for each of the lock types, finding average values for each type of lock. Then use these average values as a point of reference. For example, if the average wait time in milliseconds of RID (row) locks is 500, then you might consider any value over 500 as potentially a problem, especially if the value is a lot higher than 500, and extends over long periods of time.

If you can identify one or more types of locks causing transaction delays, then you will want to investigate further to see if you can identify what specific transactions are causing the locking. The Profiler is the best tool for this detailed analysis of locking issues. [6.5, 7.0, 2000] Updated 6-12-2006

*****

While table scans are a fact of life, and sometimes faster than index seeks, generally it is better to have fewer table scans than more. To find out how many table scans your server is performing, use the SQL Server Access Methods Object: Full Scans/sec. Note that this counter is for an entire server, not just a single database. One thing you will notice with this counter is that there often appears to a pattern of scans occurring periodically. In many cases, these are table scans SQL Server is performing on a regular basis for internal use.

What you want to look for are the random table scans that represent your application. If you see what you consider to be an inordinate number of table scans, then break out the Profiler and Index Tuning Wizard to help you determine exactly what is causing them, and if adding any indexes can help reduce the table scans. Of course, SQL may just be doing its job well, and performing table scans instead of using indexes because it is just plain more efficient. But you won't know unless you look and see what is really happening under the covers. [6.5, 7.0, 2000] Updated 6-12-2006

*****

If you suspect that your backup or restore operations are running at sub-optimal speeds, you can help verify this by using the SQL Server Backup Device Object: Device Throughput Bytes/sec. This counter will give you a good feel for how fast your backups are performing. You will also want to use the Physical Disk Object: Avg. Disk Queue Length counter to help collaborate your suspicions. Most likely, if your are having backup or restore performance issues, it is because of an I/O bottleneck.

As the DBA, it will be your job to determine the I/O bottlenecks you may be experiencing and dealing with them appropriately. For example, the cause of slow backups or restores could be something as simple as a DTS job that is running at the same time, and could be fixed by rescheduled the job. [6.5, 7.0, 2000] Updated 6-12-2006

*****

If you are using transactional replication, you may want to monitor the latency that it takes the Log Reader to move transactions from a database's transaction log until it moves it to the distribution database, and also to monitor the latency it takes the Distributor Agent to move transactions from the distribution database to the subscriber database. The total of these two figures is the amount of time it takes a transaction to get from the publication database to the subscriber database.

The counters for these two processes are the: SQL Server Replication LogReader: Delivery Latency counter and the SQL Server Replication Dist.: Delivery Latency counter.

If you see a significant increase in the latency for either of these processes, this should be a signal to you to find out what new or different has happened to cause the increased latency. [6.5, 7.0, 2000] Updated 6-12-2006

*****

A key counter to watch is the SQL Server Buffer Manager Object: Buffer Cache Hit Ratio. This indicates how often SQL Server goes to the buffer, not the hard disk, to get data. The higher this ratio, the less often SQL Server has to go to the hard disk to fetch data, and performance overall is boosted.

Unlike many of the other counters available for monitoring SQL Server, this counter averages the Buffer Cache Hit Ratio from the time the last instance of SQL Server was restarted. In other words, this counter is not a real-time measurement, but an average of all the days since SQL Server was last restarted. Because of this, if you really want to get an accurate record of what is happening in your Buffer Cache right now, you must stop and restart the SQL Server service, then letting SQL Server run several hours of normal activity before you check this figure (in order to get a good reading).

If you have not restarted SQL Server lately, then the Buffer Cache Hit Ratio figure you see may not be accurate for what is occurring now in your SQL Server, and it is possible that although your Buffer Cache Hit Ratio looks good, it may really, in fact, not be good, because of the way this counter averages this ratio over time.

In OLTP applications, this ratio should exceed 90-95%. If it doesn't, then you need to add more RAM to your server to increase performance.

In OLAP applications, the ratio could be much less because of the nature of how OLAP works. In any case, more RAM should increase the performance of SQL Server OLAP activity. [6.5, 7.0, 2000] Updated 4-3-2007

*****

Consider watching these two counters: SQLServer:Memory Manager: Total Server Memory (KB) and SQLServer:Memory Manager: Target Server Memory (KB). The first counter, SQLServer:Memory Manager: Total Server Memory (KB), tells you how much the mssqlserver service is currently using. This includes the total of the buffers committed to the SQL Server BPool and the OS buffers of the type "OS in Use."

The second counter, SQLServer:Memory Manager: Target Server Memory (KB), tells you how much memory SQL Server would like to have in order to operate efficiently. This is based on the number of buffers reserved by SQL Server when it is first started up.

If, over time, the SQLServer:Memory Manager: Total Server Memory (KB) counter is less than the SQLServer:Memory Manager: Target Server Memory (KB) counter, then this means that SQL Server has enough memory to run efficiently. On the other hand, if the SQLServer:Memory Manager: Total Server Memory (KB) counter is more or equal than the SQLServer:Memory Manager: Target Server Memory (KB) counter, this indicates that SQL Server may be under memory pressure and could use access to more physical memory. [7.0, 2000] Updated 4-3-2007

*****

SQL Server performs faster and with less resources if it can retrieve data from the buffer cache instead of reading it from disk. In some cases, memory intensive operations can force data pages out of the cache before they ideally should be flushed out. This can occur if the buffer cache is not large enough and the memory intensive operation needs more buffer space to work with. When this happens, the data pages that were flushed out to make extra room must again be read from disk, hurting performance.

There are three different SQL Server counters that you can watch to help determine if your SQL Server is experiencing such a problem.

SQL Server Buffer Mgr: Page Life Expectancy: This performance monitor counter tells you, on average, how long data pages are staying in the buffer. If this value gets below 300 seconds, this is a potential indication that your SQL Server could use more memory in order to boost performance.
SQL Server Buffer Mgr: Lazy Writes/Sec: This counter tracks how many times a second that the Lazy Writer process is moving dirty pages from the buffer to disk in order to free up buffer space. Generally speaking, this should not be a high value, say more than 20 per second or so. Ideally, it should be close to zero. If it is zero, this indicates that your SQL Server's buffer cache is plenty big and SQL Server doesn't have to free up dirty pages, instead waiting for this to occur during regular checkpoints. If this value is high, then a need for more memory is indicated.
SQL Server Buffer Mgr: Checkpoint Pages/Sec: When a checkpoint occurs, all dirty pages are written to disk. This is a normal procedure and will cause this counter to rise during the checkpoint process. What you don't want to see is a high value for this counter over time. This can indicate that the checkpoint process is running more often than it should, which can use up valuable server resources. If this has a high figure (and this will vary from server to server), consider adding more RAM to reduce how often the checkpoint occurs, or consider increasing the "recovery interval" SQL Server configuration setting.
These performance monitor counters should be considered advanced and only used to "refine" a potential diagnosis of "not enough memory" for your SQL Server. [7.0, 2000] Updated 4-3-2007

*****

A latch is in essence a "lightweight lock". From a technical perspective, a latch is a lightweight, short-term synchronization object (for those who like technical jargon). A latch acts like a lock, in that its purpose is to prevent data from changing unexpectedly. For example, when a row of data is being moved from the buffer to the SQL Server storage engine, a latch is used by SQL Server during this move (which is very quick indeed) to prevent the data in the row from being changed during this very short time period. This not only applies to rows of data, but to index information as well, as it is retrieved by SQL Server.

Just like a lock, a latch can prevent SQL Server from accessing rows in a database, which can hurt performance. Because of this, you want to minimize latch time.

SQL Server provides three different ways to measure latch activity. They include:

Average Latch Wait Time (ms): The wait time (in milliseconds) for latch requests that have to wait. Note here that this is a measurement for only those latches whose requests had to wait. In many cases, there is no wait. So keep in mind that this figure only applies for those latches that had to wait, not all latches.
Latch Waits/sec: This is the number of latch requests that could not be granted immediately. In other words, these are the amount of latches, in a one second period, that had to wait. So these are the latches measured by Average Latch Wait Time (ms).
Total Latch Wait Time (ms): This is the total latch wait time (in milliseconds) for latch requests in the last second. In essence, this is the two above numbers multiplied appropriately for the most recent second.
When reading these figures, be sure you have read the scale on Performance Monitor correctly. The scale can change from counter to counter, and this is can be confusing if you don't compare apples to apples.

Based on my experience, the Average Latch Wait Time (ms) counter will remain fairly constant over time, while you may see huge fluctuations in the other two counters, depending on what SQL Server is doing.

Because each server is somewhat different, latch activity is different on each server. Tt is a good idea to get baseline numbers for each of these counters for your typical workload. This will allow you to compare "typical" latch activity against what is happening right now, letting you know if latch activity is higher or lower than "typical".

If latch activity is higher than expected, this often indicates one of two potential problems. First, it may mean your SQL Server could use more memory. If latch activity is high, check to see what your buffer cache hit ratio is. If it is below 99%, your server could probably benefit from more RAM. If the hit ratio is above 99%, then it could be the I/O system that is contributing to the problem, and a faster I/O system might benefit your server's performance.

If you really like to get your hands dirty, here are a couple of commands you might want to experiment with to learn more about latching behavior of your software.

SELECT * FROM SYSPROCESSES WHERE waittime>0 and spid>50

This query will display currently existing SPIDs that are waiting, along with the waittype, waittime, lastwaittype, and waitresource. The lastwaittype and waitresource tells you what your latch type, and the waitresource will tell you what object the SPID is waiting on. When you run it, you may not get any results because there are no waiting occuring at the time you ran the query. But if you run the query over and over, you will eventually get some results.

DBCC SQLPerf (waitstats, clear)      --clears stats
DBCC SQLPerf (waitstats)      --give you stats as of the last clear (or SQL Server service restart)

This query displays the current latches (among other stuff), along with their Wait Type and Wait Time. You may first want to clear the stats, then run DBCC SQLPerf (waitstats) periodically over a short time period to see what latches are taking the most time.

Thanks to these forum members who contributed to this tip: josephobrien, rortloff, harryarchibald. [7.0, 2000] Updated 8-21-2005

*****

SQL Server performs faster and with less resources if it can retrieve data from the buffer cache instead of reading it from disk. In some cases, memory intensive operations can force data pages out of the cache before they ideally should be flushed out. This can occur if the buffer cache is not large enough and the memory intensive operation needs more buffer space to work with. When this happens, the data pages that were flushed out to make extra room must again be read from disk, hurting performance.

There are three different SQL Server counters that you can watch to help determine if your SQL Server is experiencing such a problem.

SQL Server Buffer Mgr: Page Life Expectancy: This performance monitor counter tells you, on average, how long data pages are staying in the buffer. If this value gets below 300 seconds, this is a potential indication that your SQL Server could use more memory in order to boost performance.
SQL Server Buffer Mgr: Lazy Writes/Sec: This counter tracks how many time a second that the Lazy Writer process is moving dirty pages from the buffer to disk in order to free up buffer space. Generally speaking, this should not be a high value, say more than 20 per second or so. Ideally, it should be close to zero. If it is zero, this indicates that your SQL Server's buffer cache is plenty big and SQL Server doesn't have to free up dirty pages, instead waiting for this to occur during regular checkpoints. If this value is high, then a need for more memory is indicated.
SQL Server Buffer Mgr: Checkpoint Pages/Sec: When a checkpoint occurs, all dirty pages are written to disk. This is a normal procedure and will cause this counter to rise during the checkpoint process. What you don't want to see is a high value for this counter over time. This can indicate that the checkpoint process is running more often than it should, which can use up valuable server resources. If this has a high figure (and this will vary from server to server), consider adding more RAM to reduce how often the checkpoint occurs, or consider increasing the "recovery interval" SQL Server configuration setting.
These performance monitor counters should be considered advanced and only used to "refine" a potential diagnosis of "not enough memory" for your SQL Server. [7.0, 2000] Updated 8-21-2005
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-5-8 15:56:50 | 显示全部楼层
以下内容转自 http://www.microsoft.com/china/t ... echnote/SQLIOPT.asp
===============
MS SQL Server 6.5 I/O 性能调整快速参考 (简述)
Henry Lau
Microsoft Corporation
1998 年 7 月

引言

本性能调整快速参考旨在帮助数据库管理员配置 Microsoft SQL Server® 以获得最佳性能,并帮助确定 SQL Server 环境中性能较差的原因。它还指导 SQL Server 应用程序开发人员如何使用 SQL Server 索引和 SQL Server 工具来分析 SQL 查询的 I/O 性能效率。

本文分为两部分:第二章和第三章扼要介绍要着重注意的最关键的性能调整项目。本文的其它部分详细讲述了 SQL Server I/O 性能主题。为了使读者成为本文中讲述的主题方面的专家,我们还在本文中给出几个很好的信息源的参考线索。

SQL Server 初始配置要检查的最重要的性能项目

最大限度地提高 I/O 速度是改善 SQL Server 性能的关键因素。增加 SQL Server 内存分配会减少 I/O 需求。为 SQL Server 提供的内存内数据高速缓存功能越强越好。在不导致 Windows NT 频繁分页的条件下,给 SQL Server 尽可能多的 RAM。

但小心不要因给 Windows NT 留的 RAM 太少而导致 Windows NT 拥挤。尽管给 SQL Server 大量内存是好事,但是数据高速缓存的增加所产生的性能改进的百分比通常是微不足道的。例如,如果 500 兆字节数据高速缓存的高速缓存命中率是 90%,那么增加到 550 兆字节时的命中率可能不过是 91%。SQL Server 性能可能不会明显改进。此外,对于有十几亿字节内存、几百的 SQL 线程等等的大型服务器来说,记住 Windows NT 可能需要比此多得多的内存来支持这样的配置。箴言:不要使 Windows NT 变得太拥挤。

Windows NT/SQL Performance Monitor 计数器显示 Windows NT 的分页: Memory: Pages/sec > 0。由于工作集剪裁和 Virtual Memory Manager 其它操作将很少使用的页转移到 Windows NT 备用和可用列表,看到某些程度的分页活动也是正常的。有关减少工作集调整的详细信息,请参见第三节中标注为“Process: Page Faults/Sec > 0 (for SQLSERVR process)”的项目。

要设置 SQL Server 内存,使用“sp_configure memory,”命令,其中 是以 2 KB 的内存块表示的。对于有大量 RAM(500+ 兆字节)仅运行 SQL Server 的基于 Windows NT 专用服务器,先将 50 兆字节留给 Windows NT,并将其余部分拨给 SQL Server。计算 的方法为(< 以字节数表示的基于 Windows NT 的服务器上可用的 RAM 总数,> - 50,000,000)/ 2000。观察 Windows NT Performance Monitor 的软内存分页和强制存储分页迹象(本文稍后部分提供了有关分页的详细信息)。SQL Server Books Online 中有一些在少于 500 兆字节 RAM 的服务器上设置内存的建议。

每次更改 SQL Server 内存值时,SQL Server 自动调整“free buffers”配置选项(至内存的 5%)。DBA 随后(调整 SQL Server 内存后)可以按需要设置可用缓冲区。下面有关 LazyWriter 的章节将更详尽地讲述 Lazy Writer 的作用、与可用缓冲区的关系,及可能需要对可用缓冲区和 max lazywrite io 所做的调整。

举例:请看一个基于 Windows NT 的服务器,它带有 2GB RAM,仅供 SQL Server 操作专用。使用上面的公式,用以下命令设置 975,000 个 2 KB 的页面:

Sp_configure memory,975000
Reconfigure with override

要使此配置选项生效,需要停止和重新启动 SQL Server。有关详细信息,请参阅“Inside Microsoft SQL Server 6.5”中的 122-124 页和第 743 页。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-5-8 16:00:42 | 显示全部楼层
以下内容转自 http://support.microsoft.com/kb/224453/
=======================
INF:了解和解决 SQL Server 7.0 或 2000 阻塞问题
文章编号 : 224453
最后修改 : 2005年10月24日
修订 : 4.0
本文的发布号曾为 CHS224453
本页

概要

更多信息

收集阻塞信息

收集 SQL Server 事件探查器跟踪信息

识别和解决常见阻塞问题

查看阻塞脚本输出

查看事件探查器数据

对常见阻塞情况分类

常见阻塞情况和解决方案

应用程序与阻塞问题

参考
概要
本文是对以下 Microsoft 知识库文章(应用于 SQL Server 6.x)中 SQL Server 7.0 的更新:
162361 (http://support.microsoft.com/kb/162361/) INF:了解和解决 SQL Server 6.x 阻塞问题
上述文章中包含的多数信息都已更新,用户可以在《SQL Server 7.0 联机丛书》的“了解和避免阻塞”主题下找到此类信息。在继续阅读本文之前,请仔细回顾该信息,此处不再赘述。本文主要讲述如何监视 SQL Server 捕获相关系统信息,以及如何分析此信息以便成功解决阻塞问题。

本文使用的标准术语与以上信息中的定义一致。在本讨论中,“连接”一词指数据库的单个登录会话。每个连接都显示为一个系统进程 ID (SPID)。每个 SPID 通常都被当作一个进程,尽管一般情况下它并不是一个独立的进程上下文。更确切地说,每个 SPID 都包含一些必需的服务器资源和数据结构,以满足来自某个给定客户端的单一连接请求。一个客户端应用程序可以建立一个或多个连接。从 SQL Server 角度来看,以下两种情况并不存在任何差异:从一台客户端计算机上的一个客户端应用程序建立多个连接和从多台客户端计算机或多个客户端应用程序建立多个连接。一个连接可以阻塞另一个连接,无论它们是来自同一应用程序还是来自两台不同客户端计算机上的不同应用程序。
回到顶端

更多信息
对于任何使用锁定式并发的关系数据库管理系统 (RDBMS) 而言,阻塞都是一项不可避免的特性。在 SQL Server 上,如果一个 SPID 锁定了某特定资源,而第二个 SPID 试图在同一资源上获取相冲突的锁类型,则会发生阻塞。通常,第一个 SPID 仅将资源锁定很短时间。当它解除锁定后,第二个连接即可自由地在该资源上获取自己的锁,并继续执行操作。这是一种正常行为,一天之中可能会发生许多次,而不会对系统性能造成任何明显的影响。

一个查询的持续时间和事务上下文将决定其锁定时限,进而决定了它们对其他查询的影响。如果查询不在事务内执行(并且没有使用任何锁提示),那么对于 SELECT 语句而言,仅在实际读取某一资源时才会锁定该资源,但查询期间并不锁定该资源。而对于 INSERT、UPDATE 和 DELETE 语句,会在查询期间进行锁定,其目的在于实现数据一致性并允许在必要时进行回滚查询。

如果查询是在事务内执行的,那么锁的保留时间将由以下因素决定:查询类型、事务隔离级别、查询中是否使用了锁提示。有关锁定说明、锁提示和事务隔离级别的信息,请参阅《SQL Server 7.0 联机丛书》中的以下主题: &#8226; “了解 SQL Server 中的锁定功能”
&#8226; “锁定体系结构”
&#8226; “锁兼容性”
&#8226; “锁定提示”
&#8226; “更改 Oracle 和 SQL Server 中的默认锁定行为”
当锁定和阻塞增加到对系统性能产生不利影响时,其原因通常有:

&#8226; 某个 SPID 将一组资源锁定了较长一段时间后,才释放这些资源。此类阻塞会随着时间推移而自行消失,但会导致系统性能降低。
&#8226; SPID 锁定了一组资源,并且不再释放这些资源。此类阻塞不会自行消失,它会无限期地妨碍对受影响资源的访问。
在上述第一种情况中,当 SPID 解除锁定后,阻塞问题会随着时间推移而自行消失。但是,情况会千变万化,因为随着时间的流逝,不同的 SPID 会在不同的资源上导致阻塞,进而产生变化的目标。为此,在上述情况下,用户很难通过 SQL Server 企业管理器或单独的 SQL 查询来解决问题。第二种情况会导致一种不一致的状态,这种状态比较容易诊断。
收集阻塞信息
为了降低阻塞问题的解决难度,数据库管理员可以使用持续监视 SQL Server 上锁定和阻塞状态的 SQL 脚本。这些脚本可以提供特定实例在一段时间的快照,让用户对该问题有一个全面的了解。有关如何用 SQL 脚本监视阻塞的说明,请参阅以下 Microsoft 知识库文章:
251004 (http://support.microsoft.com/kb/251004/) INF:如何监视 SQL Server 7.0 阻塞
271509 (http://support.microsoft.com/kb/271509/) INF:如何监视 SQL Server 2000 阻塞
本文中的脚本可执行以下任务。文中还给出了通过企业管理器或特定 SQL 查询获取该信息的方法(只要可能)。 1. 识别位于阻塞链头的 SPID。
除了使用上述文章中的脚本外,还可以使用 SQL 企业管理器识别阻塞链头,方法如下:

a.  展开服务器组;然后展开服务器。
b.  展开管理;然后展开当前活动。
c.  展开锁/进程 ID。详细信息窗格中将显示 SPID 及其阻塞信息。正在阻塞其他 SPID 的 SPID 将显示为“(阻塞)”。
注意,有时需要使用查询而不是企业管理器,因为某些类型的 tempdb 阻塞问题可能会阻止运行采用临时表操作的查询。使用直接查询,可以为您提供必要的控制能力,以避免发生此类问题。  
2. 查找发生阻塞的 SPID 正在运行的查询。
脚本方法使用以下查询确定特定 SPID 发出的命令:

DBCC INPUTBUFFER (<spid>)
                                               
也可以使用 SQL 企业管理器,方法如下:

a.  展开服务器组;然后展开服务器。
b.  展开管理;然后展开当前活动。
c.  单击进程信息。详细信息窗格中将显示 SPID。
d.  双击发生阻塞的 SPID,以查看该 SPID 执行的上批 Transact-SQL 命令。

3. 查找发生阻塞的 SPID 正使用的锁的类型。
可以通过执行 sp_lock 系统存储过程,来确定该信息。也可以使用企业管理器,方法如下:

a.  展开服务器组;然后展开服务器。
b.  展开管理;然后展开当前活动。
c.  展开锁/进程 ID。详细信息窗格中将显示 SPID 以及正使用的锁的相关信息。

4. 查找发生阻塞的 SPID 的事务嵌套层和进程状态。
@@TRANCOUNT 全局变量中提供有 SPID 的事务嵌套层。但是,也可以通过查询 sysprocesses 表,从 SPID 外部确定该信息,方法如下:

SELECT open_tran FROM SYSPROCESSES WHERE SPID=<blocking SPID number>
go
                                               
返回的值是该 SPID 的 @@TRANCOUNT 值。它显示了发生阻塞的 SPID 的事务嵌套层,该值反过来解释了为什么该 SPID 会保留锁。例如,如果该值大于零,则该 SPID 处于事务的中间位置(这种情况下,它应当保留已获取的某些锁,具体情况取决于事务隔离级别)。

使用 DBCC OPENTRAN database_name,还可以查看数据库中是否存在长期处于打开状态的事务。

收集 SQL Server 事件探查器跟踪信息
要彻底研究 SQL Server 上的阻塞问题,除了以上信息外,通常还需要捕获服务器上各种活动的事件探查器跟踪。如果某个 SPID 在一个事务中执行了多个语句,那么 DBCC INPUTBUFFER 输出中仅出现最后一个语句。但是,导致锁定依然存在的原因却可能是较早的某一个命令。利用事件探查器跟踪,可以查看当前事务中某个 SPID 执行的所有命令。可以通过以下步骤将 SQL Server 事件探查器设置为捕获跟踪。 1. 打开 SQL Server 事件探查器。
2. 在工具菜单上,单击选项。
3. 确保选中了所有事件类和所有数据列选项。
4. 单击确定。
5. 在文件菜单上,指向新建,然后单击跟踪。
6. 在常规选项卡上,指定跟踪名称和要向其中捕获数据的文件。
7. 在事件选项卡上,将下列事件类型添加到跟踪中:

标题 要添加的事件 说明
错误和警告 Exception 此事件表示出现了异常。严重度低于 25 的异常表明 SQL Server 向客户端返回了一个错误。严重度为 25 的异常为 SQL Server 内部异常,如下所述,应筛选此类异常。
杂项 Attention 此事件表示出现了关注信号。出现关注信号的常见原因是存在客户端撤消或查询超时现象。
会话 Connect 此事件表示已创建一个新的连接。
会话 Disconnect 此事件表示有一个客户端已断开连接。
会话 Existing Connection 此事件表示启动 SQL 事件探查器跟踪时存在一个连接。
TSQL RPC:Starting 此事件表示远程过程调用 (RPC) 已开始执行。
TSQL SQL:BatchStarting 此事件表示 Transact-SQL 批处理已开始执行。
存储过程 SP:StmtStarting 此事件表示存储过程中的语句开始执行的时间。存储过程名称显示在该事件的文本的开头。

此外,还可以包含以下事件,以获得更详细的信息。如果是在大容量的生产环境中运行,可以决定仅使用以上事件,因为它们足以解决阻塞问题。如果包含以下的附加事件,就可以更加容易地快速确定问题的根源,但同时也会增加系统负载与跟踪输出的大小。

标题 要添加的事件 说明
杂项 Execution Plan 此事件显示已执行的 Transact-SQL 语句的计划树。
事务 DTCTransaction 此事件跟踪两个(或多个)数据库或服务器之间的 Microsoft 分布式事务处理协调器 (MS DTC) 事务。
事务 SQLTransaction 此事件跟踪 SQL BEGIN、SAVE、COMMIT 和 ROLLBACK TRANSACTION 语句。
TSQL RPC:Completed 此事件表示已执行完远程过程调用 (RPC)。
TSQL SQL:BatchCompleted 此事件表示已执行完 Transact-SQL 批处理。
存储过程 SP:StmtCompleted 此事件表示已执行完存储过程中的语句。

8. 确保数据列选项卡上包含下面各列:开始时间、结束时间、连接 ID、SPID、事件类、文本、整数数据、二进制数据、应用程序名称、NT 用户名以及 SQL 用户名。如果包含了上述第二张表中的附加事件,还需包含以下数据列:持续时间、CPU、读取、写入。
9. 在筛选器选项卡上,排除 SQL Server 内部异常。在跟踪事件准则框中,选择严重度,然后在最大值框中键入 24。然后单击确定。

有关 SQL Server 发送给客户端的监视错误的详细信息,请参阅以下 Microsoft 知识库文章:
199037 (http://support.microsoft.com/kb/199037/) INF:捕获 SQL Server 发送给客户端的错误信息  
有关事件探查器的使用信息,请参阅《SQL Server 联机丛书》。
回到顶端

识别和解决常见阻塞问题
通过检查以上信息,可以确定多数阻塞问题的原因。本文其余内容将讨论如何使用此信息识别与解决一些常见的阻塞问题。本讨论假定您已使用了文章 Q251004(上文已提到)中的阻塞脚本来捕获发生阻塞的 SPID 的相关信息,并且已经用上述事件进行了事件探查器跟踪。
查看阻塞脚本输出
&#8226; 检查 sysprocesses 输出以确定阻塞链头。
如果没有为阻塞脚本指定快速模式,则会出现一个标题为“SPIDs at the head of blocking chains”的部分,其中列出了脚本输出中阻塞其他 SPID 的 SPID:

SPIDs at the head of blocking chains
spid   
------
9
10
                                               
如果指定了快速选项,则仍可通过查看 sysprocesses 输出来确定阻塞头。以下是一小段 sysprocesses 输出:

spid   status                         blocked
9      sleeping                       0
10     sleeping                       0
11     sleeping                       13
12     sleeping                       10
13     sleeping                       9
14     sleeping                       12
                                               
在本例中,可以看出 SPID 9 与 10 的 blocked 列都为 0,表示它们并未被阻塞,但它们都出现在其他 SPID 的 blocked 列中。这表明 SPID 9 和 10 分别是两个阻塞链的头。
&#8226; 检查 sysprocesses 输出,以了解位于阻塞链头的 SPID 的相关信息。
检查以下 sysprocesses 字段具有重要意义:

&#8226; 状态
使用此列可快速了解特定 SPID 的状态。通常情况下,sleeping 状态表示该 SPID 已执行完,正在等待应用程序提交另一项查询或批处理。runnable 状态表示该 SPID 目前正在处理查询。下表简要解释了各种状态值。

状态 含义
Background SPID 正在执行后台任务。
Sleeping SPID 当前并未执行。它通常表示该 SPID 正在等待应用程序发出命令。
Runnable SPID 当前正在执行。
Dormant 类似于 Sleeping,但 Dormant 还表示 SPID 在完成一个 RPC 事件后已被重置。重置操作清除了执行 RPC 事件过程中使用的资源。这是一种正常状态,SPID 不仅可用,并正在等待执行后续命令。
Rollback 该 SPID 处于事务回滚状态。
Defwakeup 表示 SPID 正在等待处于释放过程的资源。waitresource 字段应表示正被讨论的资源。
Spinloop 进程在尝试获取用于 SMP 系统上的并发控制的 spinlock 时正处于等待状态。

&#8226; Open_tran
该字段显示了 SPID 的事务嵌套层。如果此值大于 0,表明 SPID 处于打开的事务中,并且可能正在使用由该事务中的任意语句获取的锁。
&#8226; Lastwaittype、waittype 和 waittime
lastwaittype 字段显示了 SPID 的上一个或当前 waittype。该字段是 SQL Server 7.0 中的新字段,是 waittype 字段(保留的内部二进制列)的字符串表示形式。如果 waittype 是 0x0000,则表明 SPID 当前未处于等待状态,lastwaittype 值表示该 SPID 的上一个 waittype。如果 waittype 非零,则 lastwaittype 值表示 SPID 的当前 waittype。

有关其他 lastwaittype 和 waittype 值的简要说明,请参阅以下 Microsoft 知识库文章:
244455 (http://support.microsoft.com/kb/244455/) INF:SQL Server 7.0 中 sysprocesses waittype 和 lastwaittype 列的定义
在确定 SPID 是否处于进程中时,waittime 将十分有用。如果针对 sysprocesses 表的查询返回了 waittime 列中的一个值,并且该值小于从 sysprocesses 的上一个查询所获得的 waittime 值,则表明已获取并释放了先前的锁,目前正在等待新锁(假定 waittime 非零)。这一点可以通过比较 waitresource 和 sysprocesses 输出来验证。
&#8226; Waitresource
该字段表示 SPID 正在等待的资源。下表列出了 waitresource 的常见格式及其含义:

资源 格式 示例
表 DatabaseID:ObjectID TAB:5:261575970
其中,数据库 ID 5 是 pubs 示例数据库,对象 ID 261575970 是 titles 表。
页 DatabaseID:FileIDageID PAG:5:1:104
其中,数据库 ID 5 是 pubs,文件 ID 1 是主数据文件,页 104 是 titles 表中的一个页面。
键 DatabaseID:ObjectID:IndexID (索引键的哈希值) KEY:5:261575970:1 (5d0164fb1eac)
其中,数据库 ID 5 是 pubs,对象 ID 261575970 是 titles 表,索引 ID 1 是聚集索引,而哈希值表示特定行的索引键值。

&#8226; 其他列
其余 sysprocesses 列可让您了解问题的根源。其有效性因问题环境而异。例如,可以确定当 SPID 提交的上一批次为 (last_batch) 时,问题是否仅源于特定网络库 (net_library) 上的某些客户端(主机名)等。有关所有 sysprocesses 列的简要说明,请参阅《SQL Server 7.0 联机丛书》中的“sysprocesses (T-SQL)”主题。

注意:阻塞脚本输出中不包含 SUID 列,因为它是派生列,包含它的唯一目的是为了实现向后兼容。SQL Server 不会在内部使用它,如果对它进行查询,就会导致性能降低(因为它是派生的),所以没有包含它。

&#8226; 检查 DBCC INPUTBUFFER 输出。

对于位于阻塞链头或具有非零 waittype 的任意 SPID,阻塞脚本都将执行 DBCC INPUTBUFFER,以确定该 SPID 的当前查询:

DBCC INPUTBUFFER FOR SPID 9
EventType                              Parameters EventInfo                                    
   -------------- ---------- --------------------------------------------
Language Event 0          update titles set title = title
                                               
多数情况下,该查询会保留阻塞其他用户的锁。但是,如果 SPID 处于事务中,那么锁就可能由先前执行的查询而不是当前查询获得。因此,还应查看 SPID 的事件探查器输出,而不仅查看 inputbuffer。

注意:因为阻塞脚本包含多个步骤,所以 SPID 可能会作为阻塞链头出现在第一部分,但在执行 DBCC INPUTBUFFER 查询时,它不再阻塞,因此也就没有捕获到该 INPUTBUFFER。这表示针对该 SPID 的阻塞正在自行消失,因此它可能是问题,也可能不是问题。此时,既可以使用阻塞脚本的快速版本,以确保在清除 inputbuffer 之前捕获到它(但我们不担保您一定能做到);也可以查看该时间段内的事件探查器数据,以确定该 SPID 所执行的查询。

行 DatabaseID:FileIDageID:Slot(row) RID:5:1:104:3
其中,数据库 ID 5 是 pubs,文件 ID 1 是主数据文件,页 104 是 titles 表中的一个页面,槽 3 指示该行在此页面上的位置。
编译 DatabaseID:ObjectID TAB:5:834102012 [[COMPILE]]

其中,数据库 ID 5 是 pubs,但对象 ID 834102012 是一个存储过程。这表明该 SPID 正在等待编译此存储过程的计划。
查看事件探查器数据
在解决阻塞问题时,有效地查看事件探查器数据是非常有用的。最重要的一点是:您不必查看捕获到的所有内容,您只需要选择对自己有用的部分。事件探查器提供了可以帮助您高效地查看已捕获数据的功能。在属性对话框(单击文件菜单上的属性)中,事件探查器允许您限制所显示的数据,方法是:删除数据列或事件,按数据列分组(排序),然后应用筛选器。您可以在整个跟踪或仅在某个列中检索特定值(在编辑菜单上,单击查找)。也可以将事件探查器数据保存到 SQL Server 表中(在文件菜单上,指向另存为,然后单击表),然后对它运行 SQL 查询。

注意,应当仅在一个以前保存的跟踪文件上执行筛选。如果是在某个活动跟踪上执行这些步骤,就有可能会丢失该跟踪启动以来捕获的那些数据。首先将活动跟踪保存至某个文件或表中(在文件菜单上,单击另存为),然后重新打开它(在文件菜单上,单击打开),之后再继续。在处理已保存的跟踪文件时,筛选操作不会永久性地删除筛选掉的数据,这些数据只是没有显示而已。您可以根据需要添加和删除事件及数据列,以便集中搜索目标。

查找的内容:&#8226; 位于阻塞链头的 SPID 在当前事务中执行了哪些命令?
针对位于阻塞链头的特定 SPID,筛选跟踪数据(在文件菜单上,单击属性,然后在筛选器选项卡上指定 SPID 值)。然后,检查它在阻塞其他 SPID 之前所执行的命令。如果包含有事务事件,它们可以轻而易举地识别出事务的开始时间。此外,可以在 Text 列中搜索 BEGIN、SAVE、COMMIT 或 ROLLBACK TRANSACTION 操作。使用 sysprocesses 表中的 open_tran 值确保您已捕获所有事务事件。了解已执行的命令和事务上下文,以便确定 SPID 保留锁的原因。

请记住,事件和数据列都可以删除。不要同时查看开始和完成的事件,您需要选择其中一个。如果阻塞的 SPID 不是存储过程,请删除 SP:Starting 或 SP:Completed 事件;SQLBatch 和 RPC 事件将显示该过程调用。只有在需要查看该级别的详细信息时才查看 SP 事件。
&#8226; 位于阻塞链头的 SPID 查询的持续时间是多少?
如果包含了上述已完成的事件,则 Duration 列将显示该查询的执行时间。它有助于识别导致阻塞的长期运行的查询。要确定查询执行速度慢的原因,请依次查看 CPU、读取和写入列以及执行计划事件。

对常见阻塞情况分类
下表列出了常见症状及其可能的原因。Scenario 列中的数字与下文“常见阻塞情况和解决方案”部分中的数字相对应。Waittype、Open_Tran 和 Status 列都是 sysprocesses 信息。Resolves? 列指示阻塞是否会自行消失。

Scenario Waittype Open_Tran Status Resolves? 其他症状
1 Non-zero >= 0 runnable 当查询完成时会自行消失。 Physical_IO、CPU 和/或 Memusage 列将随时间的推移而增大。当完成时,查询的持续时间将很长。
2 0x0000 >0 sleeping 不会,但可以终止 SPID。 此 SPID 的事件探查器跟踪中可能会出现关注信号,这表明发生了查询超时或取消。
3 0x0000 >= 0 runnable 不会,直到客户端获取了所有行或关闭连接时才会消失。SPID 可以终止,但可能需要等待多达 30 秒的时间。 如果 open_tran = 0,并且当事务隔离级别为默认值 (READ COMMMITTED) 时该 SPID 就会保留锁,这可能是一个原因。
4 Varies >= 0 runnable 不会,直到客户端取消查询或关闭连接时才会消失。SPID 可以终止,但可能需要等待多达 30 秒的时间。 对于阻塞链头的 SPID 而言,sysprocesses 中的 hostname 列与它所阻塞的某个 SPID 的相同。
5 0x0000 >0 rollback 会。 此 SPID 的事件探查器跟踪中可能会出现关注信号,表明出现了查询超时或取消,或仅发出了一个回滚语句。
6 0x0000 >0 sleeping 最终,当 Windows NT 确定该会话不再处于活动状态时,该 SQL Server 连接将会断开。 sysprocesses 中的 last_batch 值比当前时间早很多。

常见阻塞情况和解决方案
下面所列情况将具有上表列出的特征。此部分提供其他详细信息(若适用)以及解决方案。 1. 正常运行,但执行时间长的查询所导致的阻塞。

解决方案:
解决此类阻塞问题的方法是设法优化查询。实际上,此类阻塞问题可能只是性能问题,您需要按照这个思路进行处理。有关解决特定查询运行缓慢问题的信息,请参阅以下 Microsoft 知识库文章:
243589 (http://support.microsoft.com/kb/243589/) 如何解决 SQL Server 7.0 或更高版本上的查询低性能问题
有关解决应用程序整体性能问题的信息,请参阅以下 Microsoft 知识库文章:
224587 (http://support.microsoft.com/kb/224587/) 如何解决 SQL Server 应用程序的性能问题
如果有一个长期运行的查询不仅阻塞了其他用户,而且无法优化,则可以考虑将它从 OLTP 环境移动到决策支持系统中。
2. 丧失了对事务嵌套层跟踪的休眠 SPID 导致的阻塞

此类阻塞通常可以由以下 SPID 识别:它正在休眠或等待命令,但其事务嵌套层(@@TRANCOUNT、sysprocesses 中的 open_tran)却大于零。如果应用程序遇到查询超时,或在没有发出所需数量的 ROLLBACK 和/或 COMMIT 语句的情况下发出了取消命令,就会发生这种情况。当 SPID 收到查询超时或取消时,它会终止当前查询和批处理,但不会自动回滚或提交事务。这是应用程序造成的,因为 SQL Server 不会认为仅由于取消了一个查询,就必须要回滚整个事务。在事件探查器跟踪中,查询超时或取消将显示为 SPID 的一个 ATTENTION 信号事件。

为证明这一点,请从查询分析器发出以下查询示例:

BEGIN TRAN
SELECT * FROM SYSOBJECTS S1, SYSOBJECTS S2

-- Issue this after canceling query
SELECT @@TRANCOUNT
ROLLBACK TRAN
                                               
当查询处于执行状态时,单击红色的取消按钮。当取消查询后,SELECT @@TRANCOUNT 会指出事务嵌套层为 1。如果它是 DELETE 或 UPDATE 查询,或在 SELECT 上使用了 HOLDLOCK,那么依然会保留所有已获得的锁。即使对于上述查询,如果在该事务的早些时候已经有另一个查询获得并保留了锁,那么当取消以上 SELECT 时,这些锁依然会被保留。

解决方案:

&#8226; 应用程序必须妥善管理事务嵌套层,否则,在取消查询后,它们可能会导致此类阻塞问题。可以通过以下方法之一解决此问题: a.  在客户端应用程序的错误处理程序中,请在出现任意错误后提交一个 IF @@TRANCOUNT > 0 ROLLBACK TRAN,即使客户端应用程序并不认为事务处于打开状态也是如此。之所以要这样做的原因是:在批处理过程中调用的存储过程,可以在客户端应用程序不知道的情况下启动事务。注意,某些条件(如取消查询)会妨碍该过程执行当前语句,因此,即使该过程具有检查 IF @@ERROR <> 0 与中止事务的逻辑,在此类情况下也不会执行该回滚代码。
b.  使用 SET XACT_ABORT ON 进行连接,或在启动了事务并且在出现错误后未进行清理的任何存储过程中使用它。当发生运行时错误时,该设置会中止所有打开的事务并将控制权交还给客户端。注意,不执行导致该错误的语句后的 T-SQL 语句。
c.  如果打开了连接,并在将连接释放回池之前运行了少量查询的应用程序(如基于 Web 的应用程序)中使用了连接池,那么在修改客户端连接以妥善处理错误之前,临时禁用连接池可能有助于缓解问题。禁用连接池并释放连接将物理注销 SQL Server 连接,进而导致服务器回滚所有打开的事务。
d.  如果启用了连接池并且目标服务器是 SQL Server 2000,那么将客户端计算机升级到 MDAC 2.6 或更高版本可能会大有益处。此版本的 MDAC 组件可以在 ODBC 驱动程序和 OLE DB 提供程序中添加代码,这样,连接就可以在再次使用前“重置”。对 sp_reset_connection 的这一调用会中止任何服务器发起的事务(由客户端 app 发起的 DTC 事务不受影响)、重置默认的数据库和 SET 选项等。注意,连接池中的连接不会被重置,除非再次使用它,因此有可能发生以下情况:用户可以打开一个事务,然后将连接释放到连接池,但该连接可能在几秒钟内都没有被再次使用,在此期间该事务将保持打开状态。如果该连接没有被再次使用,则当连接超时并被从连接池中删除后,该事务将中止。所以,客户端应用程序最好在事务的错误处理程序中中止事务,或使用 SET XACT_ABORT ON 来避免这一潜在延迟。

&#8226; 实际上,此类阻塞问题可能也是性能问题,您需要按照这个思路进行处理。如果可以减少查询执行时间,就不会发生查询超时或取消。当发生超时或取消情况时,应用程序应当有能力进行处理,这一点很重要。但检查查询性能也可能对您有所帮助。

有关解决特定查询运行缓慢问题的信息,请参阅以下 Microsoft 知识库文章:
243589 (http://support.microsoft.com/kb/243589/) 如何解决 SQL Server 7.0 或更高版本上的查询低性能问题
有关解决应用程序整体性能问题的信息,请参阅以下 Microsoft 知识库文章:
224587 (http://support.microsoft.com/kb/224587/) 如何解决 SQL Server 应用程序的性能问题
如果有一个长期运行的查询不仅阻塞了其他用户,而且无法优化,则可以考虑将它从 OLTP 环境移动到决策支持系统中。

3. 由其对应客户端应用程序没有提取所有结果行以完成操作的 SPID 导致的阻塞

当向服务器发送查询后,所有应用程序都必须立即提取所有结果行以完成操作。如果某个应用程序没有提取所有结果行,锁依然会保留在表中,进而阻塞其他用户。如果所使用的应用程序是以透明方式向服务器提交 SQL 语句,则该应用程序必须提取所有结果行。如果它没有提取所有结果行(并且无法通过配置让它完成此任务),就可能无法解决阻塞问题。为了避免发生这样的问题,可以将行为不佳的应用程序限制到某个报告或决策支持数据库中。

解决方案:

重新编写该应用程序,以便能提取所有结果行以完成操作。
4. 分布式客户端/服务器死锁导致的阻塞

与常见死锁不同的是,分布式死锁不能用 RDBMS 锁管理器检测出来。这是因为,该死锁涉及的资源中实际上仅有一个是 SQL Server 锁。该死锁的其他部分都属于 SQL Server 无法控制的客户端应用程序级别。以下两个示例展示了这种问题的发生环境,以及为了避免问题发生,应用程序可以采取的措施。

a.  使用单客户端线程的客户端/服务器分布式死锁
如果客户端具有多个打开的连接和一个执行线程,则可能发生以下分布式死锁。为了简便起见,此处使用“dbproc”一词指代客户端连接结构。

SPID1------blocked on lock------->SPID2
/\                         (正在等待将结果写回         
|                           客户端)
|                                 |
|                                 |                      Server side
| ================================|==================================
|     <-- single thread -->       |                      Client side
|                                 \/
dbproc1   <-------------------   dbproc2
(正在等待提取             (被 dbproc1 有效的阻止,正在等待
下一行)                     要运行的单个执行线程)
                                                               
在上例中,单客户端应用程序线程具有两个打开的连接。它在 dbproc1 上异步提交了一个 SQL 操作。这意味着它不等调用返回就继续执行下一步操作。然后,该应用程序又在 dbproc2 上提交了另一个 SQL 操作,并等待结果以开始处理返回的数据。当数据开始返回时(无论哪个 dbproc 先响应,假定是 dbproc1),它都会处理完成该 dbproc 上返回的所有数据。它将从 dbproc1 提取结果,直到 SPID1 被 SPID2 使用的锁阻塞为止(因为这两个查询是以异步方式在服务器上运行的)。此时,dbproc1 将无限期地等待更多数据。SPID2 并未被锁阻塞,而是在尝试向它的客户端 dbproc2 发送数据。但是,由于应用程序的单个执行线程正由 dbproc1 使用,因此在应用程序层,dbproc2 会被 dbproc1 有效地阻塞。这样就会产生 SQL Server 无法检测或解决的死锁问题,因为所涉及的资源中仅有一个是 SQL Server 资源。
b.  每个连接各用一个线程时的客户端/服务器分布式死锁

即使客户端上的每个连接都存在一个独立的线程,仍可能会发生如下所示的该分布式死锁的变体。

SPID1------blocked on lock-------->SPID2
/\                         (正在等待网络写入)        Server side
|                                  |
|                                  |
| INSERT                           |SELECT
|  ================================|==================================
|     <-- thread per dbproc -->    |                      Client side
|                                 \/
dbproc1   <-----data row-------   dbproc2
(正在等待                     (被 dbproc1 阻塞,正在等待它
插入)                         以便从其缓冲区中读取行)
                                                               
该例与示例 A 类似,不同之处在于:dbproc2 和 SPID2 都在运行 SELECT 语句,目的是执行逐行处理并通过缓冲区将每行传递给 dbproc1,以便在相同表中执行 INSERT、UPDATE 或 DELETE 语句。最后,SPID1(执行 INSERT、UPDATE 或 DELETE)将被 SPID2(执行 SELECT)使用的锁阻塞。SPID2 会将一个结果行写入客户端 dbproc2。然后,Dbproc2 将尝试把缓冲区中的行传递给 dbproc1,但却发现 dbproc1 处于忙碌状态(由于要等待 SPID1 完成当前的 INSERT,所以导致 dbproc1 被阻塞,而 SPID1 则被 SPID2 阻塞)。此时,在应用程序层,dbproc2 会被 dbproc1 阻塞,而在数据库级别,dbproc1 的 SPID (SPID1) 会被 SPID2 阻塞。这种情况会再次导致 SQL Server 无法检测到或解决的死锁问题,原因是所涉及资源中仅有一个是 SQL Server 资源。
示例 A 和示例 B 都是应用程序开发人员必须知晓的基本问题。他们必须对应用程序进行编码,以便妥善处理这类问题。

解决方案:

可以使用两种可靠的解决方案:查询超时或绑定连接。

&#8226; 查询超时
当采用查询超时时,如果出现分布式死锁,那么在发生超时时将会中断。有关使用查询超时的详细信息,请参阅 DB-Library 或 ODBC 文档。
&#8226; 绑定连接
具有多个连接的客户端可以使用该功能将这些连接绑定到一个事务空间内,以避免连接相互阻塞。有关详细信息,请参阅《SQL Server 7.0 联机丛书》中的“使用绑定连接”主题。

5. 由处于“金色”或回滚状态的 SPID 导致的阻塞

在用户定义的事务外被“终止”或取消的数据修改查询将会回滚。作为客户端计算机重启及其网络会话断开连接的附带影响,也会发生这一现象。同样,作为死锁牺牲品而被选中的查询也会回滚。回滚数据修改查询的速度通常要慢于最初应用更改的速度。例如,如果 DELETE、INSERT 或 UPDATE 语句已经运行了一个小时,那么其回滚至少也需要一个小时。这是预期行为,因为所做更改必须全部回滚,否则数据库的事物完整性和物理完整性将会受损。因为必然要进行完整回滚,所以 SQL Server 会将 SPID 标记为处于“金色”或回滚状态(这意味着它无法被“终止”或选作死锁牺牲品)。一般情况下,可以通过观察 sp_who 的输出(它可以指示 ROLLBACK 命令)来识别该状态。sysprocesses 的Status 列会指示 ROLLBACK 状态,它也会出现在 sp_who 输出中或 SQL 企业管理器当前的活动屏幕上。
解决方案:

您必须等待 SPID 回滚完所做的更改。

如果在执行该操作期间关闭服务器,数据库将在重启时进入恢复模式,并且在处理完所有打开的事务前,您将无法访问该数据库。每项事务的启动恢复时间与运行时恢复时间基本相同,并且在启动恢复期间您无法访问数据库。因此,强制服务器关闭以处理处于回滚状态的 SPID,通常达不到预期效果。

为了避免这种状况,请勿在 OLTP 系统繁忙阶段执行大批的 INSERT、UPDATE 或 DELETE 操作。请尽可能在低活动期执行此类操作。  
6. 由孤立连接导致的阻塞

如果客户端应用程序陷阱或客户端工作站重新启动,则某些情况下可能无法立即取消与服务器的网络会话。从服务器的角度来看,客户端似乎依然存在,所获取的所有锁也可能会依然保留。有关详细信息,请参阅《SQL Server 7.0 联机丛书》中的“孤立连接”主题。

解决方案:

如果客户端应用程序在没有妥善清理其资源的情况下断开了连接,可以使用 KILL 命令终止该 SPID。该 KILL 命令将以 SPID 值作为输入。例如,要终止 SPID 9,只需要发出以下命令:

KILL 9
                                               

注意:由于 KILL 命令存在检查间隔,因此完成 KILL 命令需要花费 30 秒钟。

回到顶端

应用程序与阻塞问题
当面临阻塞问题时,有一种倾向总是把重点放在服务器端调整和平台问题上。但是,这样做通常并不能解决问题,而且会浪费时间和精力,最好的方法是检查客户端应用程序和它提交的查询。就生成的数据库调用而言,无论应用程序提供的可见性级别如何,要解决阻塞问题,通常既需要检查应用程序所提交的 SQL 语句,还需要检查应用程序在查询取消、连接管理、提取所有结果行等方面的确切行为。如果开发工具不允许对连接管理、查询取消、查询超时、结果提取等内容进行显示控制,就可能无法解决阻塞问题。在为 SQL Server 选择应用程序开发工具之前,必须先仔细检查是否存在这种可能性,对于业务关键型 OLTP 环境尤其需要如此。

在数据库和应用程序的设计与构建过程中,请务必小心谨慎。尤其需要对每个查询在资源消耗、隔离级别和事务路径长度方面进行评估。每个查询和事务应尽可能的轻便。需要执行良好的连接管理规定。如果做不到这一点,应用程序就会在用户数量减少时表现出具有可接受的性能,而在用户数量增加时,性能可能会明显下降。

如果应用程序和查询设计恰当,Microsoft SQL Server 有能力在一台服务器上同时支持数千名用户,并且很少出现阻塞。有关详细信息,请参阅《SQL Server 7.0 联机丛书》中的“应用程序设计”和“了解和避免阻塞”主题。可以成功地为如此数量的用户提供服务的站点,通常使用的就是这些主题中介绍的技术。
回到顶端

参考
有关更多信息,请参考以下书籍:
Microsoft CorporationMicrosoft SQL Server 7.0 System Administration Training Kit(Microsoft SQL Server 7.0 系统管理培训工具包) (http://go.microsoft.com/fwlink/?LinkId=8376 ) Microsoft Press,2001
Microsoft CorporationMCSE Training Kit:Microsoft SQL Server 2000 System Administration(MCSE 培训工具包:Microsoft SQL Server 2000 系统管理) (http://go.microsoft.com/fwlink/?LinkId=8377 ) Microsoft Press,2001
有关更多信息,请参阅以下 Microsoft 培训和认证教程:
Microsoft Corporation2072 Administering a Microsoft SQL Server 2000 Database(管理 Microsoft SQL Server 2000 数据库) (http://www.microsoft.com/redirect.asp?PageID=159&ARAM=BOKPSS87&TARGET=/traincert/syllabi/2072afinal.asp)
Microsoft Corporation2073 Programming a Microsoft SQL Server 2000 Database(对 Microsoft SQL Server 2000 数据库进行编程)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-1-9 02:28 , Processed in 0.046587 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表