数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

避免阻塞, 让数据库性能有所保障


发布日期:2018年12月26日
 
避免阻塞, 让数据库性能有所保障

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

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

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

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

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

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

查询执行时间过长

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

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

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

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

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

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

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

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

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

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

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

针对这种情况我们就可以学着把事务简短话如这个产品信息中可能有产品类型字段那么在更新数据时我们能否不一次性进行更新而是通过产品类别字段进行控制对记录进行分次更新的如此每个类别的更新事务所耗用的时间就可能会大大缩短如此虽然操作的时候会需要多个步骤但是往往可以有效避免阻塞情况的发生提高数据库的性能

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

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

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

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

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

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

前台应用程序设计时应该允许用户临时改变主意取消查询如用户查询所有产品信息时可能会觉得响应时间比较长难以忍受此时他们就会想到取消查询在这种情况下应用程序设计时就需要设计一个取消查询按钮用户可以在查询的过程中随时点击这个按钮取消查询同时在这个按钮事件中需要注意加入一个回滚命令让数据库服务器能够及时对相关记录或者表进行解锁

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

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

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

上一篇:数据库跨平台迁移方法浅析

下一篇:SQL Data Services将成为云中完整的数据库