前期准备:

1、建表

create table T_Btree(X int primary key,Y nvarchar(4000));
            create table T_Heap(X int,Y nvarchar(4000));
            go

2、插入数据

declare @i as int =1;
            while @i<4
            begin
            insert into T_Btree(X,Y) values(@i,REPLICATE(cast(@i as nchar(1)),4000));
            insert into T_Heap(X,Y) values(@i,REPLICATE(cast(@i as nchar),4000));
            set @i = @i +1;
            end
            go

内容输出:

表格1、

select 'T_Btree'as table_name,X,Y from T_Btree;
                               go

表格2、

select 'T_Heap' as table_name ,X,Y from T_Heap;

go

连接的隔离级别设置为:

repeatable read。

set transaction isolation level repeatable read;

设置为这个级别的原因:

repeatable read。

会一直持有锁直到事务完成。

用于查看事务锁的SQL:

select lock.request_type,lock.resource_description,lock.resource_associated_entity_id,lock.request_mode,lock.request_status
                             from sys.dm_tran_locks as lock;
                             go

-------------------------------------------------------------------------------------------------------------------------------------------------------------

1、

对于  select:

A、聚集索引的情况:

begin transaction;

select 'T_Btree' as table_name ,X,Y from T_Btree;

go

锁申请情况:

锁申请情况分析:

1、database             S:是为了防止在读取数据期间database被别的事务删除。

2、page                  IS: 是为了防止在读取数据期间page被别的事务拆分。

3、key                     S:是为了防止在读取数据期间key(index)被别的事务删除。

4、object                IS:是为了防止在读取数据期间table定义被别的事务修改。

B、非聚集索引的情况:

begin transaction;

select 'T_Heap'as table_name,X,Y from T_Heap

with (index(ix_nuc_for_THeap_X));---这里是为了使用索引ix_nuc_for_THeap_X、这样就可以看使用它会加一些什么锁。
                                               go

索引使用情况:

1、database             S:是为了防止在读取数据期间database被别的事务删除。

2、page                  IS: 是为了防止在读取数据期间page被别的事务拆分。

3、key                     S: 是为了防止在读取数据期间key(index)被别的事务删除。

4、object                IS: 是为了防止在读取数据期间table定义被别的事务修改。

5、RID                    S:是为了防止在读取数据期间RID被别的事务删除。

2、

对于 update

SQL server 先可把目标数据找到、然后在做修改。打目标数据要加 S 、然后加 U 、 最后升级到 X;

A聚集索引的情况:

begin transaction
                              update T_Btree
                              set Y = 'AAA';
                              go

1、Key                       X :索引的叶子结点就是数据、要修改数据所以要加X锁。

B非聚集索引的情况:

begin transaction
                              update T_Heap
                              set Y = 'AAA';
                              go

1、RID                             X :修改后行号马上就变了、所以要加  X 锁。

2、key                             U :索引就要更新了   U  锁。

3、

delete:

A聚集索引的情况:

B聚集索引的情况:

4、

insert、

A聚集索引的情况:

begin tran;
                     insert into T_Btree(X,Y) values(4,'44444');
                     go

B聚集索引的情况:

begin tran;
                     insert into T_Heap(X,Y) values(4,'44444');
                     go

-------------------------------------------------------------------------------------------------------------------------------------------------------

总结:

select

1、 查询运行中每一条读到的记录或键值加 S 锁,如果记录不用返回就马上释放锁,如果用就根据隔离级别而定。

2、对于每一个索引都会在上面的键值加 S 锁

3、对于每个读过的页面,都加 I(意向) 锁。

4、查询要扫描的页记录越多、锁的数目也越多、查询用到的索引越多,锁的数目也越多。

所以、

1、尽量减小记录集

2、尽量使用 index scan 避免全表扫描

3、尽量设计好index ,力求一个索引就可以完成一个查询任务

upate

1、对于每个索引都会加  U 锁

2、只对要修改的记录和键加 X 锁

3、与目标列相关的索引越多,锁的数目也会越多。

4、扫描过的数据页面越多、意向锁也就越多,在扫描的过程中,对所有扫描到的记录加锁,哪怕上面没有修改。

所以、

1、尽量减小记录集

2、尽量减少无用的索引

3、尽量使用 index scan 避免全表扫描

delete

1、第一步先要找到要删除的数据、第二步删除目标数据。数据有好的索引第一步申请的锁就会少一些。

2、 delete不只是要删除数据本身,还要删除索引键,所以一张表上的索引越多,删除时要加的锁就越多,

就越容易阻塞。

所以、

只有那些有必要的索引我们才创建。

SQL Server 的各种查询和要申请的锁的更多相关文章

  1. 【转】SQL Server T-SQL高级查询

    SQL Server T-SQL高级查询 高级查询在数据库中用得是最频繁的,也是应用最广泛的. Ø 基本常用查询 --select select * from student; //查询student ...

  2. SQL SERVER中XML查询:FOR XML指定PATH

    SQL SERVER中XML查询:FOR XML指定PATH 前言 在SQL SERVER中,XML查询能够指定RAW,AUTO,EXPLICIT,PATH.本文用一些实例介绍SQL SERVER中指 ...

  3. Sql Server 存储过程中查询数据无法使用 Union(All)

    原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正 ...

  4. SQL Server数据库————连接查询和分组查询

    SQL Server数据库————连接查询和分组查询 分组查询 select 列from  <表名> where  …… group by  列 注意:跟order  by一样group ...

  5. (4.21)sql server中复制查询结果集

    在查询结果窗口中复制列标题似乎是一项简单的任务,但对于业余爱好者来说,这可能是一场噩梦. 没有可见的指令/链接/按钮,其中一个可以使用列标题单击和复制所选数据.让我们看看如何在SQL Server M ...

  6. SQL Server跨服务器查询的实现方法,OpenDataSource

    SQL Server跨服务器查询的方法我们经常需要用到,下面就为您介绍两种SQL Server跨服务器查询的方法,如果您感兴趣的话,不妨一看. SQL Server跨服务器查询方法一:用OPENDAT ...

  7. SQL Server多条件查询的实现

    SQL Server多条件查询的实现 SQL Server多条件查询我们经常会用到,下面就教您如何使用存储过程实现SQL Server多条件查询,希望对您学习SQL Server多条件查询方面有所帮助 ...

  8. sql server block如何查询并kill

    本帖提供两种做法,可避免在 SQL Server 事务锁定时产生的不正常或长时间阻塞,让用户和程序也无限期等待,甚至引起 connection pooling 连接数超过容量. 所谓的「阻塞」,是指当 ...

  9. SQL Server查询优化方法(查询速度慢的原因很多,常见如下几种) .

    今天看到一位博友的文章,觉得不错,转载一下,希望对大家有帮助,更多文章,请访问:http://blog.haoitsoft.com 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺 ...

随机推荐

  1. mysql 关键字bug

    今天运行语句 select * from order; 出现bug: ERROR 1064 (42000): You have an error in your SQL syntax; check t ...

  2. Python之路第十一天,高级(3)-线程池

    线程池 简单的线程池的实现: import queue import threading import time class ThreadPool(object): def __init__(self ...

  3. Red and Black(poj 1979 bfs)

    Red and Black Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27891   Accepted: 15142 D ...

  4. 自己动手写PHP MVC框架

    自己动手写PHP MVC框架 来自:yuansir-web.com / yuansir@live.cn 代码下载: https://github.com/yuansir/tiny-php-framew ...

  5. phalcon

    phalcon 代码内在sql 内用Ad去取数据库内的ad表. osx上没问题, centos报找不到表. 应该是centos上mysql区分大小写,可改写mysql的配置.

  6. 关于SQL SERVER 2008 R2发布订阅功能

    实现功能:主服务器维护数据的变更,从服务器需要时同步主服务器的数据. 配置:主从服务器均为SQL SERVER 2008 R2. 实现方法: 预备: 1.主从服务器需建立同一账户名及密码的账户(当时我 ...

  7. USB class总结

    以下是总结的USB的类,不同的USB类,主机询问的描述符格式和内容都不一样,具体的descriptor的内容可以查看 USB spec(http://www.usb.org/home/),如HID的s ...

  8. java生成json字符串的方法

    例1:将map对象添加一次元素(包括字符串对.数组),转换成json对象一次. 代码: package com.json; //这是使用org.json的程序: import java.util.Ha ...

  9. %{TIMESTAMP_ISO8601} 匹配2016-08-29 17:40:01,191

    2016-08-29 17:40:01,191 INFO com.zjzc.common.utils.HttpUtil - 请求接口: https://www.zjcap.cn/pay/interfa ...

  10. HDOJ-1017 A Mathematical Curiosity(淼)

    http://acm.hdu.edu.cn/showproblem.php?pid=1017 # include <stdio.h> int find(int n, int m) { in ...