SQL优化中的重要概念:锁定

原文:SQL优化中的重要概念:锁定

上篇文章讲的是事务,这篇就引出另一个重要概念,就是锁定。

当一个用户要读取另一个用户正在修改的数据,或者一个用户正在修改另一个用户正在读取的数据,或者一个用户要修改另一个用户正在修改的数据,就会出现并发问题。锁定能防止并发问题。

资源的锁定方式称为锁定模式,SQL Server中的锁定模式:共享锁,意向锁,更新锁,排他锁,架构稳定锁,架构修改锁,大批量更新锁,键范围锁。不是所有锁模式都是兼容的,如:一个加了排他锁的资源不能再加其他锁,其他事务必须等待,直到释放排他锁。

可以锁定SQL Server中的各类对象,可以锁定的资源在粒度上差异很大,从细粒度(行、键)到粗粒度(数据库)。细粒度的锁允许用户能查询那些未被锁定的行,并发性更高,但是需要更多的锁资源(每个被锁定的行都需要一个锁资源);粗粒度的锁降低了并发性,但需要的锁资源很少。

1、在SQL Server中可锁定的资源:


  1. DB(数据库)
  2. Metadata(系统元数据)
  3. Object(数据库对象:视图,函数,存储过程,触发器)
  4. Table(表)
  5. Hobt(堆或B树)
  6. Allocation Unit(按照数据的类型(数据,行溢出、大对象)分组的相关页面)
  7. Extent(8个8KB的页面)
  8. Page(8KB数据页面)
  9. Rid(行标示符对应一个堆表的行)
  10. Key(键范围上的锁、B树中的键)
  11. File
  12. Application

2、查看锁的活动


  1. select resource_type, --资源类型
  2. resource_database_id, --资源所在的数据库id
  3. resource_associated_entity_id, --数据库中与资源相关联的实体的 ID。
  4. --该值可以是对象ID、Hobt ID 或分配单元 ID,
  5. --具体视资源类型而定
  6. object_name(resource_associated_entity_id,resource_database_id),
  7. resource_lock_partition, --已分区锁资源的锁分区ID。对于未分区锁资源值为 0
  8. resource_description, --资源的说明,其中只包含从其他资源列中无法获取的信息
  9. request_session_id, --请求资源的会话
  10. request_type, --请求类型,该值为 LOCK
  11. request_mode, --请求的模式,对于已授予的请求,为已授予模式,
  12. --对于等待请求,为正在请求的模式(锁定模式)
  13. request_status --请求的当前状态,
  14. --可能值为 GRANTED、CONVERT 或 WAIT
  15. from sys.dm_tran_locks
  16. WHERE request_session_id = 361

3、控制表的锁升级

每个锁都会消耗内存资源,当锁的数量增加时,那么所需要的内存就会增加,而系统内可用的内存就会减少。如果锁占用的内存比率超过一个阀值,SQL Server会将细粒度锁(行锁)升级为粗粒度锁(表锁),这个过程就是锁升级。

锁升级的优点是可以减少锁的数量,相应的减少内存的使用量,而缺点是由于锁住了更大的资源,所以会导致阻塞,降低并发性。


  1. --默认值,不管是不是分区表,会在表级别启用锁升级
  2. ALTER TABLE t
  3. SET (lock_escalation = TABLE)
  4. --当表升级时,如果表已经分区,会在分区级别启用锁升级
  5. ALTER TABLE t
  6. SET (lock_escalation = auto)
  7. --在表级别禁用锁升级,如果用了TabLock提示或在Serializable隔离级别下查询,还是会有表锁
  8. ALTER TABLE t
  9. SET (lock_escalation = disable)

4、隔离级别

影响锁定的除了上面提到的锁定模式、锁的粒度,还有就是事务的隔离级别。

所谓隔离级别其实就是事务与事务之间相互影响的程度,比如,一个事务修改了数据,那么其他事务是否能看到这些修改的数据,无论事务是否提交。对于最高的隔离级别,这个事务所做的修改,其他任何事务都看不到;而最低的隔离级别,这个事务所做的修改,可以被其他任何事务看到。

SQL Server隔离级别:

(1)read uncommitted能解决丢失更新的问题,但是会导致脏读。

(2)read committed读取的是已提交的数据,所以解决了脏读的问题,但是会有不可重复读取的问题,也就是在一个事务中有两次读取,第一次读取的和第二次读取的同一条数据,可能值是不同的,因为在事务中的select语句在读取完之后就立即释放的共享锁,而此时有另一个事务把刚才第一个事务读取的那条数据修改了,这样第一次读和第二次读到的值就会不同。

(3)repeatable read解决了不可重复读取的问题,也就是在一个事务中的前后两次读取,读取到的数据值是一样的,但是会有幻读的可能,也就是第一次读出的数据确实和第二次读取的数据一样,但是第二次读取的记录条数可能多于第一次读取的记录条数,因为在读取的时候确实是锁住了被读取的记录,但是这个表可能添加了新的记录。

(4)serializable通过锁住查询范围内的键、键与键之间的范围来解决幻读的问题,比如where id >=5 and id <=10,加入表表中只有id为7,9的两条记录,那么5-6、7-8、9-10这3个范围都会被锁住。

(5)在ALLOW_SNAPSHOT_ISOLATION下的snapshot这种隔离级别允许读取事务一致性版本的数据,但可能不是最新的版本,也就是说在一个事务中只能读到某个版本,比如,在一个事务中有两次读取,第一次读完后,数据被另一个事务修改且事务提交了,此时进行第2次读取,那么读出来的还是和第一次读取一样的数据,这就是在一个事务中如果数据被其他事务修改了,读出来的数据也一样。优点是数据读取不会阻塞写,写也不会阻塞读取。另外,如果两个事务同时修改同一行数据,会导致更新冲突错误。

(6)在READ_COMMITTED_SNAPSHOT下的read committed隔离级别允许在同一事务中总是能读取运行的已提交的数据,而且数据读取不会阻塞写,写也不会阻塞读取,也不会导致更新冲突。


不想长大啊

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

他的留言板
关注

原文地址:https://www.cnblogs.com/lonelyxmas/p/12019935.html

时间: 2024-10-11 11:22:59

SQL优化中的重要概念:锁定的相关文章

SQL优化中的重要概念:阻塞

原文:SQL优化中的重要概念:阻塞 上一篇讲到锁定的概念,那么接下来就是如何找到由于锁定而发生阻塞的进程,并解决阻塞问题. 1.会话1,修改数据,但没有提交事务 BEGIN TRAN select @@SPID --输出:287 UPDATE t SET v = '88888' WHERE idd = 1 2.会话2,由于会话一事务没有提交,导致阻塞 BEGIN TRAN select @@SPID --输出:105 UPDATE t SET v = '888' WHERE idd = 1 --

SQL优化中的重要概念:死锁

原文:SQL优化中的重要概念:死锁 上面几篇文章讲到 事务.锁定.阻塞,最后还有一种比较极端的情况,就是死锁,这也是锁定.阻塞的一种情况. 死锁是当两个事务分别锁定了资源,而又继续请求对方已获取的资源,那么就会产生死锁. 发生死锁的原因: A.会话以不同的顺序访问表. B.会话长时间运行事务,在一个事务中更新了很多表或行,这样增加了冲突的可能. C.会话1申请了一些行锁,会话2申请了一些行锁,之后决定将其升级为表锁. 如果这些行在相同的数据页面中,并且两个会话同时在相同的页面上升级锁粒度,就会产

SQL优化中的重要概念:事务

原文:SQL优化中的重要概念:事务 sql 优化和事务有关系? 从表面上看,让sql跑的更快,似乎和事务这个概念没什么联系,但是关系数据库中最重要的2个概念就是 关系.事务. 关系,对应到sql中,是通过 主外键以及join 来实现的,当然,没有主外键,照样能关联表. 事务,是数据库提供的,特别是在高并发的情况下,保障数据一致的一种机制. 但实际上,当一个会话在修改数据,而另一个会话又要读取数据时,事务就自动发挥作用了. 通常情况下,似乎这个事务又离我们很远,似乎来无影,去无踪的概念,不过我们可

Sql Server 中锁的概念

锁的概述 一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 脏读A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复原值,此时B得到的数据就与数据库内的数据产生了不一致 不可重复读A用户读取数据,随后B用户读出该数据并修改,此时A用户再读取数据时发现前后两次的值不一致 并发控制的主要方法是封锁,锁就是在一段时间内禁止用户做

T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他

简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能.但索引可以在大多数情况下大大提升查询性能,在OLAP中尤其明显.要完全理解索引的概念,需要了解大量原理性的知识,包括B树,堆,数据库页,区,填充因子,碎片,文件组等等一系列相关知识,这些知识写一本小书也不为过.所以本文并不会深入讨论这些主题. 索引是什么 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息. 精简来说,索引是一种结构.

凸优化中的基本概念(1)

1.1 什么是凸集? 简单来说, 凸集是一个点集, 这个点集有一个性质, 就是在这个集合中任取不同的两个点x和y, 他们之间的线段(包括端点)上的点都属于这个点集,那么就说这个点集是一个凸集. 比如下图中左边的图形是凸集,而右边不是,因为我们可以找到两个点,使它们之间的线段上的点不在集合中 数学上,凸集的定义如下: 给定集合$C$,$\forall x,y\in C$,$0\leq\theta\leq 1$,如果有 $$ \theta x + (1-\theta y)\in C$$ 我们就称集合

SQL Server中的锁的简单学习

原文:SQL Server中的锁的简单学习 简介 在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于大多数数据库来说是需要同时处理多个查询的.这些查询并不会像绅士那样排队等待执行,而是会找最短的路径执行.因此,就像十字路口需要一个红绿灯那样,SQL Server也需要一个红绿灯来告诉查询:什么时候走,什么时候不可以走.这个红绿灯就是锁. 图1.查询可不会像绅士们那样按照次序进行排队 为什么需要

T-SQL查询进阶—理解SQL Server中的锁

在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于大多数数据库来说是需要同时处理多个查询的.这些查询并不会像绅士那样排队等待执行,而是会找最短的路径执行.因此,就像十字路口需要一个红绿灯那样,SQL Server也需要一个红绿灯来告诉查询:什么时候走,什么时候不可以走.这个红绿灯就是锁. 图1.查询可不会像绅士们那样按照次序进行排队 为什么需要锁 在开始谈锁之前,首先要简单了解一下事务和事务的

MySQL 数据库性能优化之SQL优化

前言 有人反馈之前几篇文章过于理论缺少实际操作细节,这篇文章就多一些可操作性的内容吧. 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需要有一些索引知识为基础. 优化目标 1.减少 IO 次数 IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当然,也是收效最明显的优化手段. 2.降低 CPU 计算 除了 IO 瓶颈之外,SQL优化中需要考虑的就