Sql Server 优化----SQL语句的执行方式与锁以及阻塞的关系
阻塞原因之一是不同的Session在访问同一张表的时候因为不兼容锁的原因造成的, 当前执行的SQL语句是否被阻塞(或者死锁),不仅跟当前表上的已有的锁有关,也会跟当前执行的SQL语句的执行方式有关 简单来说,对于表的访问方式,SQL语句的执行无非是表扫描,索引扫描,(聚集索引或者非聚集索引)索引查找等等 如果SQL语句的执行方式不当或者没有合理的索引,会造成没必要的阻塞,如果逻辑控制不当,甚至造成更严重的问题,造成数据逻辑的错误
建个测试表,下面测试演示一下
create table testIndexAndLock
(
id int identity(1,1),
col2 varchar(50)
)
GO
insert into testIndexAndLock values (NEWID())
GO 100000
很常见的业务就是,当前Session中开启了事物,执行更新或者删除某一行数据,然后再进行一系列其他的操作,当前事物提交之前,该排它锁一致保持,直到事物提交
比如下面截图:
第一个Session中利用事物和排他性操作锁定一行数据,,进行业务逻辑处理,按道理来说:目的仅仅是锁定当前行的数据(id = 6666),进行排他性操作,并没有锁定其的数据行
然后再第二个Session中,查询其他的无关的Id,按道理,上面一个Session只是锁定了id = 6666的行,怎么当前Session查询Id = 7777的行的时候会被阻塞呢?
这里就是上面说的对当前表的访问方式了,因为当前查询的表上没有任何索引,在查询id = 7777的时候,虽然id = 7777的行上没有任何锁,为什么查询还是被阻塞? 这里在执行查询id = 7777的时候,用的是全表扫描的方式执行的,此时遇到Id = 6666的这行数据的时候,因为这行数据上有排它锁,当前Session被阻塞 可以简单理解为当前Session会逐行扫描表中的数据行,在扫描的过程中,不管是表也好,数据行也好,如果遇到兼容的锁,可以正常访问, 如果遇到不兼容的锁,比如这里的查询是共享锁(s锁),遇到第一个Session中的id = 6666的这行数据的时候,发现上面是排它锁, 此时,当前Session要对该行加的锁(共享锁)与该行上的排它锁(x锁)不兼容,就只能等待,知道id = 6666这行数据上的排它锁释放或者变化与当前请求的共享锁兼容的锁,才能执行 如果id = 6666上面的排它锁一直没有释放或者变化为兼容共享锁的锁类型,当前Session就一直等待 表现为当前Session被阻塞 这种问题解决办法也很简单,类似现象如果要不被阻塞,要么等到第一个Session的排它锁释放,要么就换一种查询的方式 尝试在表的Id列上建立一个索引,当然聚集索引也可以,目的是防止查询的时候以全表扫描的方式进行
在第二个Session中执行上面的查询,查询Id = 7777的数据行,可以发现这个查询可以顺利完成
这个就是通过索引改变查询的执行计划,避免全表扫描的时候遇到任何一行数据上有排它锁造成阻塞的情况。 这里说的索引,并不仅仅是为了提高效率,更重要的是改变了查询的执行方式,避免遇到表上有排他性锁的锁在成阻塞的情况。
索引的作用不仅仅是提高查询效率,更重要的是避免全表扫描的过程中遇到排它锁被阻塞的情况,对减少阻塞有一定的帮助作用。
相关文章
- SQL Server执行计划
- 深入了解SQL Server数据库的线程与纤程
- SQL Server 2019安装和卸载
- 了解Sql Server的执行计划
- SQL Server调优系列基础篇
- 解决开启SQL Server sql Always on Group 事务日志增大的问题
- SQL Server - Management Studio - Client Statistics - Wait time on server replies vs Client processing time
- self join in sql server
- is-a,has-a,like-a是什么 sql server中,N''表示什么意思? 关于SQL SERVER的N前缀的理解
- CASE函数 sql server——分组查询(方法和思想) ref和out 一般处理程序结合反射技术统一执行客户端请求 遍历查询结果集,update数据 HBuilder设置APP状态栏
- C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法
- sql 批量修改,Update Select 嵌套更新或批量更新一句SQL语句搞定,
- Sql Server表中删除重复记录最简单方法(多字段重复)
- 实战演练 | SQL Server 中的磁盘加密
- 《PowerShell V3——SQL Server 2012数据库自动化运维权威指南》——第1章 开始使用SQL Server和PowerShell 1.1 简介
- 《PowerShell V3——SQL Server 2012数据库自动化运维权威指南》——2.2 列出SQL Server实例
- sql: MySQL and Microsoft SQL Server Stored Procedures IN, OUT using csharp code
- Sql Server 优化 SQL 查询:如何写出高性能SQL语句
- SQL Server 查询处理中的各个阶段(SQL执行顺序)
- 程序员眼中的 SQL Server-执行计划教会我如何创建索引?
- SQL Server之字符串函数
- SQL Server查询优化器:最佳执行计划
- RDS SQL Server - 专题分享 - 巧用执行计划缓存之Key Lookup
- sql server兼容级别
- sql server作业报错,但里面的步骤是执行成功的
- (4.51)sql server用 sp_getapplock 实现串行执行的存储过程
- sql server作业报错:从ICassFactory为CLSID为{17BCA6E8-A950-497E-B2F9-AF6AA475916F}的COM组件创建实例失败,原因是出现以下错误:c001f011.(Microsoft.Server.manageDTS)
- sql server监控清单
- 利用PowerDesigner绘制PDM生成SQL Server数据库
- SQL Server Profiler监控执行语句