了解和避免阻塞

 

 

了解和避免阻塞

当来自应用程序的第一个连接控制锁而第二个连接需要相冲突的锁类型时,将发生阻塞。其结果是强制第二个连接等待,而在第一个连接上阻塞。不管是来自同一应用程序还是另外一台客户机上单独的应用程序,一个连接都可以阻塞另一个连接。

说明  一些需要锁保护的操作可能不明显,例如系统目录表和索引上的锁。

大多数阻塞问题的发生是因为一个进程控制锁的时间过长,导致阻塞的进程链都在其它进程上等待锁。

常见的阻塞情形包括:

  • 提交执行时间长的查询。

长时间运行的查询会阻塞其它查询。例如,影响很多行的 DELETE 或 UPDATE 操作能获取很多锁,这些锁不论是否升级到表锁都阻塞其它查询。因此,一般不要将长时间运行的决策支持查询和联机事务处理 (OLTP) 查询混在一起。解决方案是想办法优化查询,如更改索引、将大的复杂查询分成简单的查询或在空闲时间或单独的计算机上运行查询。

查询运行时间长并由此导致阻塞的一个原因是这些查询不适当地使用游标。游标可能是在结果集中浏览的便利方法,但使用游标可能比使用面向集合的查询慢。

  • 取消没有提交或回滚的查询。

如果应用程序取消查询(如使用开放式数据库连接 (ODBC) sqlcancel 函数)但没有同时发出所需数目的 ROLLBACK 和 COMMIT 语句,则会发生这种情况。取消查询并不自动回滚或提交事务。取消查询后,所有在事务内获取的锁都将保留。应用程序必须提交或回滚已取消的事务,从而正确地管理事务嵌套级。

  • 应用程序没处理完所有结果。

将查询发送到服务器后,所有应用程序必须立即完成提取所有结果行。如果应用程序没有提取所有结果行,锁可能会留在表上而阻塞其他用户。如果使用的应用程序将 Transact-SQL 语句透明地提交给服务器,则该应用程序必须提取所有结果行。如果应用程序没这样做(如果无法配置它执行此操作),则可能无法解决阻塞问题。为避免此问题,可以将这些应用程序限制在报表或决策支持数据库上。

  • 分布式客户端/服务器死锁

与常规死锁不同,分布式死锁无法由 Microsoft® SQL Server™ 2000 自动检测到。如果应用程序打开多个与 SQL Server 的连接并异步提交查询,则可能会发生分布式客户端/服务器死锁

例如,一个客户端应用程序线程有两个开放式连接。该线程异步启动事务并在第一个连接上发出查询。应用程序随后启动其它事务,在另一个连接上发出查询并等待结果。当 SQL Server 返回其中一个连接的结果时,应用程序开始处理这些结果。应用程序就这样处理结果,直到生成结果的查询被另一个连接上执行的查询阻塞而导致再没有可用的结果为止。此时第一个连接阻塞,无限期等待处理更多的结果。第二个连接没有在锁上阻塞,但仍试图将结果返回给应用程序。然而,由于应用程序阻塞而在第一个连接上等待结果,第二个连接的结果将得不到处理。

若要避免此问题,请执行下列任一操作:

    • 对每个查询使用查询超时。
    • 对每个查询使用锁定超时。有关更多信息,请参见自定义锁超时
    • 使用绑定连接。有关更多信息,请参见使用绑定连接

SQL Server 本质上是受客户端应用程序操纵的傀儡。客户端应用程序对服务器上获取的锁几乎有完全的控制(并对锁负责)。虽然 SQL Server 锁管理器自动使用锁保护事务,但这受客户端应用程序发出的查询类型和对结果的处理方式的直接鼓动。因此,大多数阻塞问题的解决方案都涉及检查客户端应用程序。

阻塞问题常要求检查应用程序提交的 SQL 语句本身,以及检查与连接管理、所有结果行的处理等有关的应用程序行为本身。如果开发工具不允许显式控制连接管理、查询超时、结果处理等,阻塞问题可能得不到解决。

设计应用程序以避免阻塞的准则包括:

  • 不要使用或设计使用户得以填写编辑框的应用程序,编辑框会生成长时间运行的查询。例如,不要使用或设计提示用户输入的应用程序,允许某些字段保留空白或允许输入通配符。这可能导致应用程序提交运行时间过长的查询,从而导致阻塞问题。
  • 不要使用或设计使用户得以在事务内输入内容的应用程序。
  • 允许取消查询。
  • 使用查询或锁定超时,防止失控查询和避免分布式死锁
  • 立即完成提取所有结果行。
  • 使事务尽可能简短。
  • 显式控制连接管理。
  • 在所预计的并发用户全负荷下对应用程序进行应力测试。

死锁减至最少

虽然不能完全避免死锁,但可以使死锁的数量减至最少。将死锁减至最少可以增加事务的吞吐量并减少系统开销,因为只有很少的事务:

  • 回滚,而回滚会取消事务执行的所有工作。
  • 由于死锁时回滚而由应用程序重新提交。

下列方法有助于最大限度地降低死锁

  • 按同一顺序访问对象。
  • 避免事务中的用户交互。
  • 保持事务简短并在一个批处理中。
  • 使用低隔离级别。
  • 使用绑定连接。
按同一顺序访问对象

如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。例如,如果两个并发事务获得 Supplier 表上的锁,然后获得 Part 表上的锁,则在其中一个事务完成之前,另一个事务被阻塞在 Supplier 表上。第一个事务提交或回滚后,第二个事务继续进行。不发生死锁。将存储过程用于所有的数据修改可以标准化访问对象的顺序。

避免事务中的用户交互

避免编写包含用户交互的事务,因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,如果事务正在等待用户输入,而用户去吃午餐了或者甚至回家过周末了,则用户将此事务挂起使之不能完成。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。

保持事务简短并在一个批处理中

在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁

保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。

使用低隔离级别

确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取(未修改)的数据,而不必等待第一个事务完成。使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)可以缩短持有共享锁的时间,从而降低了锁定争夺。

使用绑定连接

使用绑定连接使同一应用程序所打开的两个或多个连接可以相互合作。次级连接所获得的任何锁可以象由主连接获得的锁那样持有,反之亦然,因此不会相互阻塞。

使用绑定连接

绑定连接允许两个或多个连接共享同一个事务和锁定。绑定连接可以对同一个数据进行操作,而不会有锁定冲突。绑定连接可以从同一个应用程序内的多个连接中创建,也可以从使用不同连接的多个应用程序中创建。绑定连接使得协调多个连接上的操作更加容易。

若要加入到绑定连接中,连接必须调用 sp_getbindtoken srv_getbindtoken(开放数据服务),以获得一个绑定令牌。绑定令牌是一个字符串,它唯一地标识每个绑定事务。然后绑定令牌将发送给加入到绑定连接的其它连接。其它连接通过调用 sp_bindsession,并使用从第一个连接中接收到的绑定令牌绑定到事务上。

必须从创建第一个连接的应用程序代码将绑定令牌传送到创建随后每个绑定连接的应用程序代码中。应用程序不能使用 Transact-SQL 语句或 API 函数获取由另一个进程启动的事务绑定令牌。可以用来传送绑定令牌的方法有:

  • 如果所有连接都是从同一个应用程序进程创建而来,那么绑定令牌可以存储在全局内存中,也可以作为参数传递到函数中。
  • 如果连接是从不同的应用程序进程创建而来,那么绑定令牌可以使用进程间通讯 (IPC),如远程过程调用 (RPC) 或动态数据交换 (DDE)来传输。
  • Microsoft® SQL Server™ 中可以将绑定令牌存储在某个表中,该表应能够被要绑定到第一个连接的进程读取。

在一组绑定连接中,任意时刻只能有一个连接是活动的。如果一个连接正在服务器上执行一个语句,或者包含由服务器挂起的结果,那么共享同一事务空间的其它连接都不能访问该服务器,直到当前的连接完成处理或取消了当前的语句为止。如果服务器很忙,那么就会出现错误,表明事务空间正在使用,该连接应该稍后再试。

绑定连接的类型

有两种绑定连接类型:本地和分布式。

  • 本地绑定连接

允许绑定连接共享单个服务器上的单个事务的事务空间。

  • 分布式绑定连接

允许绑定连接在用 Microsoft 分布式事务处理协调器 (MS DTC) 提交或回滚整个事务之前,共享跨越两个或多个服务器的同一事务。

分布式绑定连接的标识不是用字符串绑定令牌,而是用分布式事务标识号。如果本地事务中涉及到绑定连接,而且该连接使用 SET REMOTE_PROC_TRANSACTIONS ON 执行远程服务器上的 RPC,则 MS DTC 将该本地绑定事务自动升级到分布式绑定事务,并且 MS DTC 会话也会启动。

何时使用绑定连接

绑定连接在开发必须执行 Transact-SQL 语句的扩展存储过程方面很有用,这些 Transact-SQL 语句代表调用这些绑定连接的进程。让调用进程在绑定令牌中作为扩展存储过程的一个参数进行传递,可使该过程加入到调用进程的事务空间中,从而将扩展存储过程与该调用进程结合在一起。

绑定连接可以用来开发三层应用程序,其中,商业逻辑用单独的程序表示,而这些程序在单个商业事务上协同工作。

下面的绑定连接示例阐明了两个连接如何能够访问同一个事务。某个顾客决定在本地的一个百货商店购买产品。售货员访问销售事务系统,在销售事务表中插入一行,其中包括信用卡授权号码。对同一服务器建立两个连接,连接 C1 和连接 C2。C1 开始一个事务,将产品销售行添加到销售表中。必须将信用卡授权号码添加到新的销售事务行中。在信用卡授权进程中,扩展存储过程创建连接 C2,通过电话线拨出到信用卡公司并使用信用卡授权号码修改销售事务行。只有使用绑定连接,才能实现两个连接访问同一行而不出现锁定冲突。

应用程序设计

应用程序设计在决定使用 Microsoft® SQL Server™ 2000 的系统的性能方面起关键作用。将客户端视为控制实体而非数据库服务器。客户端确定查询类型、何时提交查询以及如何处理查询结果。这反过来对服务器上的锁类型和持续时间、I/O 活动量以及处理 (CPU) 负荷等产生主要影响,并由此影响总体性能的优劣。

正因为如此,在应用程序的设计阶段做出正确决策十分重要。然而,即使在使用总控应用程序时(这种情况下似乎不可能更改客户端应用程序)出现性能问题,也不会改变影响性能的根本因素:客户端具有支配作用,如果不更改客户端则许多性能问题都无法解决。设计优秀的应用程序允许 SQL Server 支持成千上万的并发用户。反之,设计差的应用程序会防碍即使是最强大的服务器平台处理少数用户的请求。

客户端应用程序的设计准则包括:

  • 消除过多的网络流量。

客户端和 SQL Server 之间的网络往返通常是数据库应用程序性能较差的首要原因,甚至超过了服务器和客户端之间传送的数据量这一因素的影响。网络往返描述在客户端应用程序和 SQL Server 之间为每个批处理和结果集发送的会话流量。通过使用存储过程,可以将网络往返减到最小。例如,如果应用程序根据从 SQL Server 收到的数据值采取不同的操作,只要可能就应直接在存储过程中做出决定,从而消除过多的网络流量。

如果存储过程中有多个语句,则默认情况下,SQL Server 在每个语句完成时给客户端应用程序发送一条消息,详细说明每个语句所影响的行数。大多数应用程序不需要这些消息。如果确信应用程序不需要它们,可以禁用这些消息,以提高慢速网络的性能。请使用 SET NOCOUNT 会话设置为应用程序禁用这些消息。有关更多信息,请参见 SET NOCOUNT

  • 使用小结果集。

检索没必要大的结果集(如包含上千行)并在客户端浏览将增加 CPU 和网络 I/O 的负载,使应用程序的远程使用能力降低并限制多用户可伸缩性。最好将应用程序设计为提示用户输入足够的信息,以便查询提交后生成大小适中的结果集。有关更多信息,请参见使用高效数据检索优化应用程序性能

可帮助实现上述目标的应用程序设计技术包括:在生成查询时对通配符进行控制,强制某些输入字段,不允许特殊查询,以及使用 TOP、PERCENT 或 SET ROWCOUNT 等 Transact-SQL 语句限制查询返回的行数。有关更多信息,请参见使用 TOP 和 PERCENT 限制结果集SET ROWCOUNT

  • 允许在用户需要重新控制应用程序时取消正在执行的查询。

应用程序决不应强迫用户重新启动客户机以取消查询。无视这一点将导致无法解决的性能问题。如果应用程序取消查询(例如使用开放式数据库连接 (ODBC) sqlcancel 函数取消查询),应对事务级别予以适当的考虑。例如,取消查询并不会提交或回滚用户定义的事务。取消查询后,所有在事务内获取的锁都将保留。因此,在取消查询后始终要提交或回滚事务。同样的情况也适用于可用于取消查询的 DB-Library 和其它应用程序接口 (API)。

  • 始终实现查询或锁定超时。

不要让查询无限期运行。调用适当的 API 以设置查询超时。例如,使用 ODBC SQLSetStmtOption 函数。

有关设置查询超时的更多信息,请参见 ODBC API 文档。

有关设置锁定超时的更多信息,请参见自定义锁超时

  • 不要使用不允许显式控制发送到 SQL Server SQL 语句的应用程序开发工具。

如果工具基于更高级的对象透明地生成 Transact-SQL 语句,而且不提供诸如查询取消、查询超时和完全事务控制等关键功能,则不要使用这类工具。如果应用程序生成透明的 SQL 语句,通常不可能维护好的性能或解决性能问题,因为在这种情况下不允许对事务和锁定问题进行显式控制,而这一点对性能状况至关重要。

  • 不要将决策支持和联机事务处理 (OLTP) 查询混在一起。有关更多信息,请参见联机事务处理与决策支持
  • 只在必要时才使用游标。

游标是关系数据库中的有用工具,但使用游标完成任务始终比使用面向集合的 SQL 语句花费多。

当使用面向集合的 SQL 语句时,客户端应用程序让服务器更新满足指定条件的记录集。服务器决定如何作为单个工作单元完成更新。当通过游标更新时,客户端应用程序要求服务器为每行维护行锁或版本信息,而这只是为了客户端在提取行后请求更新行。

而且,使用游标意味着服务器通常要在临时存储中维护客户端的状态信息,如用户在服务器上的当前行集。为众多客户端维护这类状态信息需消耗大量的服务器资源。对于关系数据库,更好的策略是让客户端应用程序快速进出,以便在各次调用之间不在服务器上维护客户端的状态信息。面向集合的 SQL 语句支持此策略。

然而,如果查询使用游标,请确定如果使用更高效的游标类型(如快速只进游标)或单个查询能否更高效地编写游标查询。有关更多信息,请参见使用高效数据检索优化应用程序性能

不要设计或使用在未取消查询时就停止处理结果行的应用程序。否则通常会导致阻塞和降低性能。有关更多信息,请参见了解和避免阻塞

  • 确保将应用程序设计为可避免死锁。有关更多信息,请参见死锁减至最少
  • 确保已设置所有能够优化分布式查询性能的适当选项。有关更多信息,请参见优化分布式查询

处理死锁

当一个应用程序提交的事务被选作死锁牺牲品时,该事务将自动终止并回滚,然后系统将 1205 号错误信息返回给应用程序。因为任何提交 SQL 查询的应用程序都可以被选定作为死锁牺牲品,应用程序应该有错误处理程序来捕获错误信息 1205。如果应用程序没有捕获到错误,它可能继续处理而未意识到事务已经回滚,这样应用程序就会出错。

通过实现捕获 1205 号错误信息的错误处理程序,使应用程序得以处理该死锁情况并采取补救措施(例如,可以自动重新提交陷入死锁中的查询)。自动重新提交查询可能意味着用户不必知道发生了死锁

在自动重新提交查询前,客户端程序应暂停,以便为控制所需锁的事务提供完成并释放这些锁的机会。这样,在事务试图获得那些锁时,可以最大限度地降低事务被死锁的可能性。

说明  死锁不总是取消返回错误的批处理操作。对于客户端程序来说进行错误检查是非常重要的,因为死锁并不总是返回失败的返回代码。在大多数情况下,如果发生死锁且批处理未自动取消,则应用程序应取消当前查询。如果没有进行此操作,则 SQL Server 在连接上可能仍有未决结果等待客户端处理。如果没有处理未决结果,则在该应用程序下一次试图向 SQL Server 发送命令时将发生错误。

 

SQL 事件探查器方案

通常情况下,使用 SQL 事件探查器可以:

  • 查找执行最差的查询

例如,可以创建跟踪来捕获与 TSQL Stored Procedure 事件类(尤其是 RPC:CompletedSQL:BatchCompleted)相关的事件。在这个跟踪内包含所有数据列,按 Duration 分组并指定事件准则。例如,如果指定事件的 Duration 至少为 1,000 毫秒,则可以跟踪中排除运行时间短的事件。根据需要可以增大 Duration 的最小值。如果想一次只监视一个数据库,为 Database ID 事件准则指定一个值。

  • 识别死锁原因

例如,可以创建一个跟踪来捕获与 TSQLStored Procedure 事件类(RPC:StartingSQL:BatchStarting)以及 Locks 事件类(Lock:DeadlockLock:Deadlock Chain)相关的事件。在这个跟踪内包括所有数据列并按 Event Class 分组。如果想一次只监视一个数据库,为 Database ID 事件准则指定一个值。

若要查看死锁所涉及的连接,执行下列操作之一:

    • 打开包含捕获的数据的跟踪,按 ClientProcessID 将数据分组并展开死锁所涉及的两个连接。
    • 将捕获的数据保存到一个跟踪文件,然后打开这个跟踪文件两次,使其显示在两个单独的 SQL 事件探查器窗口内。按 ClientProcessID 将捕获的数据分组,然后展开死锁所涉及的进程 ID;每个死锁连接都在一个单独的窗口内。平铺窗口以查看导致死锁的事件。
  • 监视存储过程的性能

例如,可以创建一个跟踪来捕获与 Stored Procedure 事件类(SP:CompletedSP:StartingSP:StmtCompletedSP:StmtStarting)和 TSQL 事件类(SQL:BatchStarting SQL:BatchCompleted)相关的事件。在这个跟踪内包含所有数据列并按 ClientProcessID 分组。如果想一次只监视一个数据库,为 Database ID 事件准则指定一个值。同样,如果想一次只监视一个存储过程,为 Object ID 事件准则指定一个值。

  • 审核 Microsoft® SQL Server™ 活动

可以使用 SQL 事件探查器审核 SQL Server 中的活动。例如,如果安全管理员需要随时了解谁登录到了服务器,可以创建 SQL 事件探查器跟踪,提供已登录到服务器或从服务器注销的用户的完整视图。之后,可出于法律目的使用这些信息记录活动,和出于技术目的使用这些信息跟踪违反安全策略的行为。

若要设置 SQL 事件探查器跟踪来跟踪已登录到服务器或从服务器注销的用户,请执行下列操作:

  1. 创建跟踪并选择 Audit Login Event
  2. 若要返回适当的信息,请指定下列数据列:

EventClass(默认情况下选定)

EventSubClass

LoginSID

LoginName

  • 监视每个用户的 Transact-SQL 活动。

可以创建跟踪来捕获与 Sessions 事件类、ExistingConnection 和 TSQL 事件类相关的事件。将所有数据列包含在此跟踪内,不要指定任何事件准则,并按 DBUserName 将捕获的事件分组。

涉及并行的死锁

涉及并行的死锁总是涉及线程和锁资源。单独的并行不会导致死锁。跟踪标记 1204 报告的信息允许用户跟踪单独的并行工作线程并查找导致死锁的其它资源争夺问题。跟踪死锁时,把所有的并行线程(例如,具有相同 SPID 的线程)视为单个单元。

跟踪标记 1204 在循环中报告如下参与者:处理协调器、使用者和发生器。处理协调器是子线程的创建者和破坏者。发生器生成使用者等待的信息。

要解决涉及一个非并行 SPID AA 和并行 SPID BB 的死锁,请执行解决两个非并行 SPID 之间的死锁时用到的同样过程。

示例
A. 涉及并行的死锁

下面的例子说明了处理协调器、使用者和发生器在跟踪标记 1204 中是如何表示的。

Node:2
Port: 0x2b968100  Xid Slot: -1, EC: 0x2bba53b0, SPID:59 ECID: 0 (Coordinator), Exchange
Wait Type :e_etypeClose
Coordinator: EC = 0x2bba53b0, SPID:59 ECID: 0, Not Blocking
Consumer List::
Consumer: Xid Slot: 0, EC = 0x2bbda090, SPID:59 ECID: 2, Blocking
Consumer: Xid Slot: 1, EC = 0x2bbce090, SPID:59 ECID: 4, Blocking
Consumer: Xid Slot: 4, EC = 0x2bb60090, SPID:59 ECID: 1, Blocking
Consumer: Xid Slot: 5, EC = 0x2bbd4090, SPID:59 ECID: 3, Blocking
Producer List::
Producer: Xid Slot: 2, EC = 0x2bb64090, SPID:59 ECID: 6, Blocking
Producer: Xid Slot: 3, EC = 0x2bbbe090, SPID:59 ECID: 8, Blocking
Producer: Xid Slot: 6, EC = 0x2bbca090, SPID:59 ECID: 5, Blocking
Producer: Xid Slot: 7, EC = 0x2bbc6090, SPID:59 ECID: 7, Blocking
B. 带分支的死锁

跟踪标记 1204 报告有分支的死锁循环。例如,下面的引用显示了节点 6 的一个分支,其中一个线程在 RID 1:1:1253:0 上有独占的 (X) 锁,而 SPID 55 正在等待一个更新的 (U) 锁,SPID 60 刚好请求了另一个更新的 (U) 锁。

-- next branch --
Node:6
 RID: 1:1:1253:0                CleanCnt:5 Mode: X Flags: 0x2 
 Wait List:
   Owner:0x98b9d7c Mode: U        Flg:0x0 Ref:1  Life:02000000 SPID:55 ECID:0
 Requested By:
   ResType:LockOwner Stype:'OR' Mode: U SPID:60
 
-- next branch --
 
Node:9
 RID: 1:1:1253:0                CleanCnt:5 Mode: X Flags: 0x2
 Wait List:
   Owner:0x98b9d7c Mode: U        Flg:0x0 Ref:1 Life:02000000 SPID:55 ECID:0
 Requested By:
   ResType:LockOwner Stype:'OR' Mode: U SPID:59 ECID:0 Ec:(0x9b09494) Value:0x98b9c5c Cost:(0/0)
-- next branch --

在涉及并行和线程的死锁中,一个线程可以等待多个线程。因此,跟踪标记 1204 报告中"下一个分支"的每个实例都代表等待下一个特定的线程。

 

涉及线程的死锁

在涉及线程的死锁中,跟踪标记 1204 提供了有关授予语句权限的线程和等待权限的线程的信息。

下面的例子中,这几个线程 (SPID 64、60、59、57 和 55) 有 UPDATE 语句权限,而 SPID 51 在等待列表中。

Node:1
 Granted thread list:
   SPID: 64 ECID: 0 Statement Type: UPDATE
   SPID: 60 ECID: 0 Statement Type: UPDATE
   SPID: 59 ECID: 0 Statement Type: UPDATE
   SPID: 57 ECID: 0 Statement Type: UPDATE
   SPID: 55 ECID: 0 Statement Type: UPDATE
 Wait thread list:
   SPID: 51 ECID: 0 Statement Type: UNKNOWN TOKEN

UNKNOWN TOKEN 表示线程当前没在执行批处理。

SQL Server 中自定义锁定

虽然 Microsoft® SQL Server™ 2000 自动执行锁定,但它仍可以通过以下方法自定义应用程序中的锁定:

  • 处理死锁和设置死锁优先级。
  • 处理超时和设置锁超时持续时间。
  • 设置事务隔离级别。
  • SELECTINSERTUPDATE DELETE 语句使用表级锁定提示。
  • 配置索引的锁定粒度。

通过有效的网络流量、磁盘 I/O 和 CPU 时间,可获得最短的响应时间和最大的吞吐量,从而获得最佳性能。为达到此目的,需要彻底分析应用程序的要求,了解数据的逻辑结构和物理结构,并评估和协商解决数据库使用冲突(如联机事务处理 (OLTP) 与决策支持)的平衡措施。

响应时间与吞吐量

响应时间是这样度量的:以可视的形式确认正在处理查询并将结果集中的首行返回给用户所需的时间长度。

吞吐量是服务器在给定时间内处理的查询总数的度量值。

随着用户数的增加,对服务器资源的竞争也随之增加,转而导致响应时间增加和总体吞吐量减少。

影响性能的因素

下列方面影响 SQL Server 的性能:

  • 系统资源(硬件)
  • Microsoft Windows NT® 4.0 Windows® 2000 操作系统
  • 数据库应用程序
  • 客户端应用程序
  • 网络

必须知道在正常工作条件下的合理性能级别,才能监视这些方面。为此需建立服务器性能基线,即以定期的间隔监视 Microsoft® SQL Server™ 性能(即使没有发生问题时)。

解决问题

可以监视下列方面以解决问题:

  • SQL Server 存储过程或用户应用程序提交的批处理 SQL 语句。
  • 用户活动(如阻塞锁或死锁)。
  • 硬件活动(如磁盘使用)

问题可以包括:

  • 应用程序开发错误(包括错误编写 Transact-SQL 语句)。
  • 硬件错误(如磁盘错误或与网络有关的错误)。
  • 由于数据库设计不正确导致的过多阻塞。

可以使用 SQL 事件探查器监视和解决 Transact-SQL 问题和与应用程序有关的问题。可以使用系统监视器(Windows NT 4.0 中的性能监视器)监视硬件问题和其它与系统有关的问题。

 

posted on 2005-11-03 14:21  Peter.zhou  阅读(1343)  评论(0)    收藏  举报

导航