若将会话 B 先加上 SET LOCK_TIMEOUT 3000 的设置,如下,则会话 B 会先等待 3 秒钟,才抛出代号 1222 的「锁请求已超时」错误信息:
SET LOCK_TIMEOUT 3000 UPDATE Orders SET EmployeeID=7 WHERE OrderID=10248 --SET LOCK_TIMEOUT -1 |
执行结果:
消息 1222,级别 16,状态 51,第 3 行
已超过了锁请求超时时段。
语句已终止。
-------------------------------------------------------------------------------------------
另根据我之前写的文章「30 分钟快快乐乐学 SQL Performance Tuning」所述:
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.html
撰写不当的 SQL 语句,会让数据库的索引无法使用,造成全表扫描或全聚集索引扫描。例如不当的:NOT、OR 算符使用,或是直接用 + 号做来串接两个字段当作 WHERE 条件,都可能造成索引失效,变成全表扫描,除了性能变差之外,此时若这句不良的 SQL 语句,是本帖前述会话 B 的语句,由于会造成全表扫描,因此就一定会被会话 A 的事务阻塞 (因为扫描全表时,一定也会读到 OrderID=10248 的这一条记录)。
下方的 SQL 语句,由于 OrderID 字段有设索引,因此下图 1 的「执行计划」,会以算法中的「二分搜寻法」在索引中快速查找 OrderID=10250 的记录
SELECT * FROM Orders WHERE OrderID=10250 SELECT * FROM Orders WHERE OrderID=10250 AND ShipCountry='Brazil' |
图 1 有正确使用到索引的 SQL 语句,以垂直的方向使用索引。用 AND 算符时,只要有任一个字段有加上索引,就能受惠于索引的好处,并避免全表扫描