IT星球论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 3762|回复: 0

SQL Server 并发性系列(一)并发性问题自测及分析

[复制链接]

1999

主题

1

好友

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

优秀会员 助人为乐 辛勤工作 技术精英 多才多艺 优秀班竹 灌水天才 星球管理 宣传大使 灌水之王 财富勋章 版主勋章 动漫勋章 勤奋会员 论坛精英 PS高手 心 8 闪游皮肤 双鱼座 8★8➹ 志愿者 乖

发表于 2013-4-27 14:06:12 |显示全部楼层
关于锁、阻塞,很多人都存在一些疑惑,但是都知道,它是导致性能问题发生的原因之一。在此,我们先来一个自测,然后分析和探究阻塞的形成。
--建立一张测试表
Create Table T1 (Id INT NOT NULL, Value INT)
INSERT T1 VALUES (1,100)
INSERT T1 VALUES (2,200)
--在SSMS中打开两个会话窗口,先后执行下面语句

问题1:请问会话2中哪条语句能返回数据?
问题2:SQL Server 最常见的锁,有如下几种。请问会话1使用了哪种锁引起会话2被阻塞?

问题3:SQL Server 中常见的锁定的对象如下,请问会话1哪个对象上面的锁引起会话2被阻塞?

问题4:如果在会话2中,我们执行下面的查询,返回的数据时多少?
SELECT * FROM T1 (NOLOCK) WHERE Id =1
A,100
B,110
问题5:在修改或删除一条记录是,SQL Server 会排他锁定该记录,如果在修改1万条记录呢?该事务排他锁定的是什么?
A,1万条记录
B,表
答案1:没有答案,所有的语句都被阻塞无法执行
答案2:B,排他锁引起了阻塞
答案3:D,表上没有聚集索引,是堆表,而且只修改了一条记录,因此是堆表的行锁
答案4:B,NOLOCK返回脏读的结果,即返回未提交的更改
答案5:B,SQL Server 的表上获得超过5,000 个锁时,会升级为表锁
锁可以防止用户读取未提交的数据,还可以防止多个用户尝试同时更改同一数据。如果不进行锁定,对数据执行的查询可能会返回数据库中尚未提交的数据,从而产生意外的结果。
SQL Server 插入、修改、删除记录时,通常使用排他锁独占该记录的访问。由于SQL Server 默认使用提交读(Read Committed)事务隔离级别。在该事务隔离级别下,排他锁定进行的记录被查询的时候,既不返回修改前的数据,也不返回修改后的数据,直到修改的事务Commit 或 Rollback,这种现象我们称之为“阻塞”,是一种正常现象。
在业务高峰期表数据被频繁或者大量的进行增、删、改时,用户进行的查询由于阻塞的发生,导致执行时间变长,效率非常低下,用户的体验非常不好。我们称这种现象为并发性问题。
T-SQL在对少量记录进行操作时,只会排他锁定这些记录。但是其他的查询结果虽然不包含这些记录,但是由于缺乏索引或者不适合使用索引时,会进行表扫描或者聚集索引扫描获得结果。但是在扫描到排他锁定的记录是,会等待该记录的排他锁释放,这样就明明使用的行锁,却造成了表锁的效果。
如果一条T-SQL 语句修改或删除大量的记录时(超过5000条),SQL Server 会这个修改的会话分配表排他锁,即整个表被排他访问,这种现象我们称之为锁升级。
这里总结一下本文五个问题体现的知识点:
1.锁是一种正常现象,但不是导致性能低下的原因,不合理的阻塞才是性能的杀手;
2.绝大部分的阻塞是因为缺乏合理的索引导致的;
3.保持事务足够的简短,一条语句中修改、删除大量的数据,可能会导致行锁升级为表锁,造成较大的性能影响,应该尽量避免,例如:安排在非繁忙时间进行、分成若干个小批次进行;
4.适当的使用nolock或者提交读、快照事务隔离级别,可以提高并发性;
5.SQL 2005 以后加入的行版本控制,可以提高 SQL Server 并发性;
注:在《SQL Server 并发性系列(二)使用行版本控制提高 SQL Server 并发性》中介绍
6.将查询和修改放在不同的数据库服务器上,实现读写分离的,也是一种不错的提高并发性的方法;
注:在《SQL Server 并发性系列(三)读写分离提高 SQL Server 并发性》中介绍
本文转载自:http://www.canway.net/Lists/Canw ... 747A43215699709205A


该会员没有填写今日想说内容.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

回顶部