阻塞原因之一是不同的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语句的执行方式与锁以及阻塞的关系的更多相关文章

  1. Sql Server 优化 SQL 查询:如何写出高性能SQL语句

    1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条 ...

  2. SQL Server查看Sql语句执行的耗时和IO消耗

    原文:SQL Server查看Sql语句执行的耗时和IO消耗 在做系统过程中,经常需要针对某些场景进行性能优化,那么如何判定性能优化的效果呢?肯定需要知道优化之前Sql语句的耗时和优化之后Sql语句的 ...

  3. Sql server的Merge语句,源表中如果有重复数据会导致执行报错

    用过sql server的Merge语句的开发人员都应该很清楚Merge用来做表数据的插入/更新是非常方便的,但是其中有一个问题值得关注,那就是Merge语句中的源表中不能出现重复的数据,我们举例来说 ...

  4. Linux下用freetds执行SQL Server的sql语句和存储过程

    Linux下用freetds执行SQL Server的sql语句和存储过程 http://www.linuxidc.com/Linux/2012-06/61617.htm freetds相关 http ...

  5. 深入SQL Server优化【推荐】

    深入sql server优化,MSSQL优化,T-SQL优化,查询优化 十步优化SQL Server 中的数据访问故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性 ...

  6. SQL Server优化的方法

    SQL Server优化的方法<一>   查询速度慢的原因很多,常见如下几种:   1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)   2.I/O吞吐量小,形成了 ...

  7. SQL Server中的三种Join方式

      1.测试数据准备 参考:Sql Server中的表访问方式Table Scan, Index Scan, Index Seek 这篇博客中的实验数据准备.这两篇博客使用了相同的实验数据. 2.SQ ...

  8. 【SQL Server 优化性能的几个方面】(转)

    转自:http://blog.csdn.net/feixianxxx/article/details/5524819     SQL Server 优化性能的几个方面 (一).数据库的设计 可以参看最 ...

  9. SQL Server优化技巧——如何避免查询条件OR引起的性能问题

    之前写过一篇博客"SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析",里面介绍了OR可能会引起全表扫描或索引扫描的各种案例,以及如何优化查询条件中含有OR的SQL语句的 ...

随机推荐

  1. Java中类似单元格之间的计算公式解析,如A1+B3-B4

    package net.riking.util; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; ...

  2. luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树

    Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...

  3. ListUtil集合操作常用方法类

    * 集合操作常用方法类. * <p> * * @author 柯 */ public class ListUtil { /** * 判断List不为空,非空返回true,空则返回false ...

  4. sqlserver系统表使用

    SELECT s.table_catalog as 数据库名, o.name as 表名, c.name as 列名FROM INFORMATION_SCHEMA.TABLES s,--库 sys.o ...

  5. anaconda安装的TensorFlow版本没有model这个模块

    一.采用git bash来安装,确认已经安装了git 二.手动找到TensorFlow的模块文件夹地址,若不知道,输入以下两行代码: import tensorflow as tf tf.__path ...

  6. 3.在eclipse中创建Web项目,并部署到Tomcat上

    1.找到创建web项目的菜单 2.创建web项目并选择web环境 3.查看创建好的web项目结构 4.在web项目的webContent文件夹下创建jsp页面 5.查看是否创建jsp页面成功,并编辑j ...

  7. 3. IDEA 的样式设置和快捷键设置

    一.样式设置 首先打开IDEA之后,点击任务栏的“File”→Settings 二.设置快捷键 1.首先打开IDEA之后,点击任务栏的“File”. 2.在下拉列表中中选择“Settings” 3.在 ...

  8. 反射常用API

    反射所有功能都是通过class API来实现的 class常用API有: 1.class.GETINTERFACES():获得这个类实现的接口. 2.class.getMethods() Method ...

  9. Oracle中如何判断字符串是否全为数字

    Oracle中如何判断字符串是否全为数字 学习了:http://www.cnblogs.com/zrcoffee/archive/2012/12/11/2812744.html 本文介绍了判断字符串是 ...

  10. svn 插件安装

    方法一:link安装  1.从官网下载site-1.6.18.zip文件. 2.从中解压出features与 plugins目录.拷贝到D:\MyEclipse\myPlugin\svn里面,其他的* ...