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

很常见的业务就是,当前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语句的执行方式与锁以及阻塞的关系的更多相关文章
- Sql Server 优化 SQL 查询:如何写出高性能SQL语句
1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条 ...
- SQL Server查看Sql语句执行的耗时和IO消耗
原文:SQL Server查看Sql语句执行的耗时和IO消耗 在做系统过程中,经常需要针对某些场景进行性能优化,那么如何判定性能优化的效果呢?肯定需要知道优化之前Sql语句的耗时和优化之后Sql语句的 ...
- Sql server的Merge语句,源表中如果有重复数据会导致执行报错
用过sql server的Merge语句的开发人员都应该很清楚Merge用来做表数据的插入/更新是非常方便的,但是其中有一个问题值得关注,那就是Merge语句中的源表中不能出现重复的数据,我们举例来说 ...
- Linux下用freetds执行SQL Server的sql语句和存储过程
Linux下用freetds执行SQL Server的sql语句和存储过程 http://www.linuxidc.com/Linux/2012-06/61617.htm freetds相关 http ...
- 深入SQL Server优化【推荐】
深入sql server优化,MSSQL优化,T-SQL优化,查询优化 十步优化SQL Server 中的数据访问故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性 ...
- SQL Server优化的方法
SQL Server优化的方法<一> 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了 ...
- SQL Server中的三种Join方式
1.测试数据准备 参考:Sql Server中的表访问方式Table Scan, Index Scan, Index Seek 这篇博客中的实验数据准备.这两篇博客使用了相同的实验数据. 2.SQ ...
- 【SQL Server 优化性能的几个方面】(转)
转自:http://blog.csdn.net/feixianxxx/article/details/5524819 SQL Server 优化性能的几个方面 (一).数据库的设计 可以参看最 ...
- SQL Server优化技巧——如何避免查询条件OR引起的性能问题
之前写过一篇博客"SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析",里面介绍了OR可能会引起全表扫描或索引扫描的各种案例,以及如何优化查询条件中含有OR的SQL语句的 ...
随机推荐
- 【深度学习框架】使用PyTorch进行数据处理
在深度学习中,数据的处理对于神经网络的训练来说十分重要,良好的数据(包括图像.文本.语音等)处理不仅可以加速模型的训练,同时也直接关系到模型的效果.本文以处理图像数据为例,记录一些使用PyTorc ...
- TFS代码迁移Git
描述 将TFS上的代码迁移到Git做版本控制. 参考地址 tfs-git下载:https://github.com/git-tfs/git-tfs/releases chocolatey安装:http ...
- mysql 基础教程
创建数据库: CREATE DATABASE --DATABASE 或者 SCHEMA数据库集合 IF NOT EXISTS db_name CHARACTER SET utf8 COLLATE ut ...
- Docker 搭建 ELK 读取微服务项目的日志文件
思路: 在docker搭建elasticsearch与kibana来展示日志,在微服务部署的机子上部署logstash来收集日志传到elasticsearch中,通过kibana来展示,logstas ...
- 关于git修改和查看用户名邮箱
git 查看/修改用户名.密码 查看用户名和邮箱地址: $ git config user.name $ git config user.email 修改用户名和邮箱地址: $ git config ...
- P2310 loidc,看看海
P2310 loidc,看看海 题目背景 loidc喜欢大海.在他放假的时候他经常一个人跑到海边独自玩耍. 在浪花的冲击下,他可以忘记打代码的烦躁,真是惬意极了. 虽然今天是周六,但今天可是11.8号 ...
- [python]win32api
安装完pywin32以后一定要重启啊!!!!!!!!!!!!
- sendfile学习
参考 https://zhuanlan.zhihu.com/p/20768200?refer=auxten 而成本很多时候的体现就是对计算资源的消耗,其中最重要的一个资源就是CPU资源. Sendfi ...
- HDU 1515
简单题,直接用STACK模拟整个过程. 模拟出栈时,应注意保护现场,等到递归完成后返回. #include <iostream> #include <string.h> #in ...
- [Wikioi 1226]倒水问题
题目描写叙述 Description 有两个无刻度标志的水壶.分别可装 x 升和 y 升 ( x,y 为整数且均不大于 100 )的水. 设另有一水 缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶 ...