偶是测试新手,希望前辈们能多多指教。

让数据库性能测试性能有所保障【转载】

上一篇 / 下一篇  2009-07-10 17:16:19 / 个人分类:IT相关知识

 
2009年01月09日 星期五 15:07
虽然说SQL Server数据库本身提供了很好的锁管理机制。但是,从某一方面来说,其实数据库只是一些客户端应用程序的“傀儡”。这主要是因为客户端应用程序对服务器上获取的锁几乎有完全的控制能力。客户端应用程序发出的查询请求以及对结果的处理方式,往往具有直接的控制能力。所以,如果应用程序在设计上稍有不合理的情况时,就会因为锁机制而导致阻塞。

  如当遇到如下几种情形时,就可能会导致阻塞情况的发生。

  一、客户端取消查询后没有回滚实务。

  查询是大部分应用程序经常发生的作业。但是,用户通过前台客户端应用程序查询后台数据库时,有时候往往会因为各种原因取消查询。如用户打开查询窗口后,因为死机或者用户觉得反映速度慢强制取消查询。但是,当客户端取消查询时,若没有加上回滚事务的语句,则此时,因为用户已经向服务器发送了查询请求,所以,后台数据库中所涉及的表,都已经加L上了锁。故即使用户取消查询后,所有在事务内获取的锁都将会保留。此时,若其他用户也需要查询这些表或者用户重新打开查询窗口想通过输入查询条件来提高系统响应速度时,就会发生阻塞的现象。

  二、客户端没有及时取得所有查询的结果。

  通常情况下,用户将查询请求发送到服务器之后,前台应用程序必须立即完成提取所有结果行。如果应用程序没有提取所有结果行的话,就会产生一个问题。因为只要应用程序没有及时提取所有结果,锁可能会留在表上而阻塞其他用户。既然应用程序已经将SQ语句递交给服务器,则该应用程序就必须提取所有的结果行。若应用程序不遵循这个原则的话(如因为一时疏漏而没有配置),就无法从根本上解决阻塞问题。

  三、查询执行时间过长。

  有些查询会耗用比较长的时间。如因为查询语句设计不合理或者查询设计到的表与记录比较多时,都会使得查询的执行时间加长。如有时候用户需要对纪录进行Update或者Delete操作时,如果涉及的行比较多时,就会获取很多的锁。这些锁无论是否最终升级到表锁,都会阻塞其他查询。

  故通常情况下,不要将长时间运行的决策支持查询和联机事务处理查询混在一起。

  当数据库遇到阻塞时,往往需要检查应用程序递交的SQL语句本身,以及检查与连接管理、所有结果行的处理等有关的应用程序行为。通常情况下,为了避免因锁冲突所导致的阻塞,笔者有如下建议。

  建议一:查询完成后提取所有的结果行。

  有些应用程序为了提高用户查询的响应速度,会有选择的提取所需要的记录。这个“小聪明”看起来很合理,但是,却会造成更大的浪费。因为查询结果没有及时提取的话,锁就不能释放。当其他人查询数据时,就会发生阻塞。

  所以,笔者建议在应用程序设计时,对于数据库中查询的记录要及时的提取。可以通过其他方式,如添加查询条件、或者后台查询的方式,来提高查询的效率。同时,在应用程序层面设置合理的缓存,也可以非常明显的提高查询效率。

  建议二:在事务执行时不要让用户输入内容。

  虽然在事务执性的过程中,可以让用户参与进来,以提高互动性。但是,我们数据库管理员往往不建议这么做。因为若要用户在事务执行过程中输入参数,会延长事务的执行时间。虽然人比较聪明,但是其反应速度仍然没有电脑那么快。所以,在执行过程中加入让用户参与的过程,会延长事务的等待时间。故除非有特殊的需要,不要在应用程序的执行过程中,提醒用户输入参数。一些事务执行必须的参数,最好在事先就提供。如可以通过变量等预先把需要的参数传入进去。

  建议三:使事务尽可能的简短。

  笔者认为,数据库管理员应该把一些问题简单化。当某个需求需要很多SQL语句才能够完成时,不妨把任务进行分解。同时,也把事务分解成一些简短的事务。

  如数据库中一张产品信息表,其记录数量有二百万条。现在处于管理的需要,把一次性更改其中的一百五十万条记录时。若通过一个事务进行更改,则其时间会比较长。若其中还牵涉到级联更新的话,则时间会更长。

  针对这种情况,我们就可以学着把事务简短话。如这个产品信息中,可能有产品类型字段。那么在更新数据时,我们能否不一次性进行更新。而是通过产品类别字段进行控制,

对记录进行分次更新的。如此每个类别的更新事务所耗用的时间就可能会大大缩短。如此虽然操作的时候,会需要多个步骤。但是,往往可以有效避免阻塞情况的发生,提高数据库的性能。

  建议四:子查询与列表框,最好不要同时使用。

  有时候在应用程序设计的时候,通过列表框确实可以提高用户输入的速度与准确率,但是,若前台应用程序没有缓存机制的话,往往会造成阻塞。

  如在一个订单管理系统中,可能需要频繁的输入销售代表。为了用户输入的方便,销售代表往往设计成一个列表框。每次需要输入时,前台应用程序都会从后台中进行查询销售代表信息(如果应用程序没有涉及缓存)。一方面,子查询的速度本来就比较慢;其次,列表框会生成长时间运行的查询。这两个方面碰在一起,就可能导致应用程序提高运行时间过程的查询。从而对其他用户的查询,如系统管理员需要维护用户信息,而造成阻塞。

  所以,在应用程序设计时,子查询最好少用。而子查询与列表框同时使用,更需要禁止。若避免不了的话,则要在应用程序中实现缓存机制。如此的话,应用程序需要销售代表信息的时候,就会从应用程序缓存中取得,而不会每次都去查询数据库。

  同时,可以在这个列表框中设计“重新查询”功能。当用户信息有变更,如系统管理员加入了一个新的销售代表。在没有进行重新查询之前,由于应用程序是从自身的缓存中取得数据,所以没有刚更新的内容。此时,用户就需要运行重新查询功能,让前台应用程序重新从数据库中查询信息。这种设计,就可以提高列表框与子查询的执行时间,有效避免阻塞问题。

  建议五:在取消查询时设置回退事务。

  前台应用程序设计时,应该允许用户临时改变主意,取消查询。如用户查询所有产品信息时,可能会觉得响应时间比较长,难以忍受。此时,他们就会想到取消查询。在这种情况下,

应用程序设计时就需要设计一个取消查询按钮。用户可以在查询的过程中随时点击这个按钮取消查询。同时,在这个按钮事件中,需要注意加入一个回滚命令。让数据库服务器能够及时对相关记录或者表进行解锁。

  同时最好能够采用锁或者查询超时机制。这主要是因为,有时候大量查询也会耗费用户主机的大量资源,而导致客户机死机。此时,若能够采用查询或者锁超时机制,即在查询超时过后,数据库服务器自动对相关对象进行解锁。这也是数据库管理员需要跟程序开发人员协商的一个问题。

  另外,对数据库连接采取显式控制、在所预计的并发用户全负荷下对应用程序进行承受能力测试、使用邦定连接、对每个查询使用查询超时与锁超时等等,这些手段都可以有效避免锁冲突产生的阻塞。当数据库管理员发现有阻塞的症状时,可以从这些方面出发,寻找解决的措施。

  从以上的分析中可以看出,SQL Server数据库锁是一把双刃剑。其在保障数据库数据一致性的同时,也会给数据库造成一些负面影响。如何把这些负面影响降到最低,就是我们数据库管理员的任务。在应用程序设计时,遵循如上建议,可以有效解决因锁问题产生的阻塞问题,提高数据库的性能。可见,要从根本上解决阻塞问题,需要数据库管理人员与程序开发人员共同努力。


TAG:

 

评分:0

我来说两句

Open Toolbar