SQL Server阻塞查询语句


SQL Server阻塞查询语句 

SQL Server的阻塞查询主要来自sys.sysprocesses。通常在处理时需要加入其它相关的视图或表,例如如sys.dm_exec_connectionssys.dm_exec_sql_text。通过如下几个语句的查询,可以找到阻塞的语句。


点击(此处)折叠或打开

  1. SELECT BL.SPID BLOCKING_SESSION,
  2.        BL.BLOCKED BLOCKED_SESSION,
  3.        ST.TEXT BLOCKEDTEXT
  4.   FROM (SELECT SPID, BLOCKED
  5.           FROM SYS.SYSPROCESSES A
  6.          WHERE BLOCKED > 0
  7.            AND NOT EXISTS (SELECT 1
  8.                   FROM SYS.SYSPROCESSES B
  9.                  WHERE BLOCKED > 0
  10.                    AND A.BLOCKED = B.SPID)
  11.         UNION
  12.         SELECT SPID, BLOCKED
  13.           FROM SYS.SYSPROCESSES
  14.          WHERE BLOCKED > 0) BL,
  15.        (SELECT T.TEXT, C.SESSION_ID
  16.           FROM SYS.DM_EXEC_CONNECTIONS C
  17.          CROSS APPLY SYS.DM_EXEC_SQL_TEXT(C.MOST_RECENT_SQL_HANDLE) T) ST
  18.  WHERE BL.BLOCKED = ST.SESSION_ID;



点击(此处)折叠或打开

  1. SELECT A.BLOCKING_SESSION_ID, A.WAIT_DURATION_MS, A.SESSION_ID, B.TEXT
  2.   FROM SYS.DM_OS_WAITING_TASKS A,
  3.        (SELECT T.TEXT, C.SESSION_ID
  4.           FROM SYS.DM_EXEC_CONNECTIONS C
  5.          CROSS APPLY SYS.DM_EXEC_SQL_TEXT(C.MOST_RECENT_SQL_HANDLE) T) B
  6.  WHERE A.SESSION_ID = B.SESSION_ID
  7.    AND A.BLOCKING_SESSION_ID IS NOT NULL;


包含阻塞与被阻塞的SQL脚本

点击(此处)折叠或打开

  1. SELECT BL.SPID BLOCKING_SESSION,
  2.        BL.BLOCKED BLOCKED_SESSION,
  3.        ST.TEXT BLOCKEDTEXT,
  4.        SB.TEXT BLOCKINGTEXT
  5.   FROM (SELECT SPID, BLOCKED
  6.           FROM SYS.SYSPROCESSES A
  7.          WHERE BLOCKED > 0
  8.            AND NOT EXISTS (SELECT 1
  9.                   FROM SYS.SYSPROCESSES B
  10.                  WHERE BLOCKED > 0
  11.                    AND A.BLOCKED = B.SPID)
  12.         UNION
  13.         SELECT SPID, BLOCKED
  14.           FROM SYS.SYSPROCESSES
  15.          WHERE BLOCKED > 0) BL,
  16.        (SELECT T.TEXT, C.SESSION_ID
  17.           FROM SYS.DM_EXEC_CONNECTIONS C
  18.          CROSS APPLY SYS.DM_EXEC_SQL_TEXT(C.MOST_RECENT_SQL_HANDLE) T) ST,
  19.        (SELECT T.TEXT, C.SESSION_ID
  20.           FROM SYS.DM_EXEC_CONNECTIONS C
  21.          CROSS APPLY SYS.DM_EXEC_SQL_TEXT(C.MOST_RECENT_SQL_HANDLE) T) SB
  22.  WHERE BL.BLOCKED = ST.SESSION_ID
  23.    AND BL.SPID = SB.SESSION_ID;


  查询死锁:

点击(此处)折叠或打开

  1. SELECT *
  2.   FROM MASTER ..SYSPROCESSES
  3.  WHERE DB_NAME(DBID) = '数据库名'
  4.    AND SPID <> @@SPID
  5.    AND DBID <> 0
  6.    AND BLOCKED > 0;








About Me

...............................................................................................................................

本文整理自网络

本文在itpub(http://blog.itpub.net/26736162)、博客园http://www.cnblogs.com/lhrbest和个人微信公众号(xiaomaimiaolhr)上有同步更新

本文pdf版小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● QQ群:230161599     微信群:私聊

联系我请加QQ好友(642808185),注明添加缘由

文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

版权所有,欢迎分享本文,转载请保留出处

...............................................................................................................................

拿起手机使用微信客户端扫描下边的左边图片来关注小麦苗的微信公众号:xiaomaimiaolhr,扫描右边的二维码加入小麦苗的QQ群,学习最实用的数据库技术。

 ico_mailme_02.png  DBA笔试面试讲解

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26736162/viewspace-2135726/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26736162/viewspace-2135726/

SQL Server 中,`UPDATE FROM` 语句可能导致阻塞的原因主要与事务隔离级别、锁的获取与释放机制以及并发操作有关。以下是对该问题的详细分析及可能的解决方案。 ### 阻塞原因分析 1. **锁的获取与等待** `UPDATE FROM` 语句通常涉及多个表的连接操作,这会导致 SQL Server 在执行更新时需要对多个表的数据行加锁。如果这些行已经被其他事务以排他锁(X 锁)持有,当前事务将无法立即获取所需的共享锁(S 锁)或更新锁(U 锁),从而进入等待状态,形成阻塞[^2]。 2. **事务长时间运行** 如果 `UPDATE FROM` 语句涉及大量数据更新,事务可能运行时间较长。在此期间,SQL Server 会保持对已修改数据的锁,直到事务提交或回滚。其他事务如果尝试访问这些被锁定的数据,将被阻塞[^1]。 3. **死锁风险** 在高并发环境中,`UPDATE FROM` 与其他操作(如 `SELECT` 或 `UPDATE`)并发执行时,可能形成死锁。例如,事务 A 正在等待事务 B 释放某行的锁,而事务 B 同时也在等待事务 A 释放另一行的锁,导致双方都无法继续执行[^2]。 4. **事务一致性与回滚开销** 如果某个事务因异常被终止(如通过 `KILL` 命令强制结束),SQL Server 会自动回滚该事务中所有未提交的更改。回滚操作同样需要对数据加锁,可能导致其他事务在回滚完成前被阻塞[^1]。 ### 解决方法 1. **优化查询与索引** 确保 `UPDATE FROM` 语句中涉及的表具有适当的索引,尤其是连接列和更新列。良好的索引设计可以显著减少扫描的数据量,从而减少锁的持有时间,降低阻塞概率。 2. **使用较低的事务隔离级别** 将事务隔离级别设置为 `READ COMMITTED SNAPSHOT` 或 `SNAPSHOT`,可以减少锁竞争,避免因读写冲突导致的阻塞。此方法通过行版本控制实现,允许读取操作不阻塞写入操作。 3. **控制事务大小与执行时间** 避免在一个事务中执行大规模的 `UPDATE FROM` 操作。可以将大事务拆分为多个小事务,逐批更新数据,减少锁的持有时间,降低阻塞风险。 4. **使用 `WITH (NOLOCK)` 提示(适用于 `SELECT`)** 在 `SELECT` 查询中使用 `WITH (NOLOCK)` 提示可以跳过共享锁的获取,避免因等待锁而被阻塞。但需注意,这种方式可能导致读取未提交的数据(脏读)。 ```sql SELECT * FROM Table1 WITH (NOLOCK) INNER JOIN Table2 ON Table1.ID = Table2.RefID ``` 5. **启用阻塞监控与自动捕获** 可以通过以下配置启用 SQL Server阻塞监控功能,以便及时发现并分析阻塞源头: ```sql EXEC sp_configure 'show advanced options', 1; GO RECONFIGURE; GO EXEC sp_configure 'blocked process threshold', 10; GO RECONFIGURE; GO ``` 上述配置将启用高级选项并设置阻塞阈值为 10 秒,超过该时间的阻塞将被记录[^3]。 6. **避免死锁的最佳实践** - 保持事务操作顺序一致,确保所有事务按相同顺序访问资源。 - 在事务中尽量减少对数据库的访问次数,缩短事务持续时间。 - 使用 `TRY`/`CATCH` 结构捕获死锁错误并实现重试机制。 ```sql BEGIN TRY BEGIN TRANSACTION; -- 执行 UPDATE FROM 操作 UPDATE t1 SET t1.Column1 = t2.Column2 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.RefID; COMMIT TRANSACTION; END TRY BEGIN CATCH IF (ERROR_NUMBER() = 1205) -- 死锁错误代码 BEGIN -- 重试逻辑 END ROLLBACK TRANSACTION; END CATCH ``` ### 总结 `UPDATE FROM` 语句SQL Server 中可能导致阻塞的主要原因包括锁竞争、事务长时间运行、死锁风险以及事务回滚开销。通过优化查询、调整事务隔离级别、控制事务大小、启用阻塞监控等手段,可以有效减少阻塞的发生,提升系统并发性能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值