在SQL Serve里停用行和页层级锁
今天我想谈下SQL Server里另一个非常有趣的话题:在SQL Server里停用行和页层级锁。在SQL Server里,每次你重建一个索引,你可以使用ALLOW_ROW_LOCKS 和ALLOW_PAGE_LOCKS选项来指定,SQLServer在用读写访问你的数据时,应该获得行和页锁。我们从内部看下,当我们停用这些锁时会发生什么。
停用行层级锁
让我们在一个聚集索引上运行一个简单的REBUILD操作,这里我们停用行层级锁:
-- Disable row level locks
ALTER INDEX idx_ci ON Foo REBUILD
WITH (ALLOW_ROW_LOCKS = OFF)
GO
如你从锁层级里知道的,SQL Server从表层级、页层级和行级别获取锁。现在让我们在一个显式事务里运行一个SELECT语句,并且我们用HOLDLOCK查询提示来把持共享锁直到事务结束。
-- SQL Server acquires in Repeatable Read a Shared Lock on the Page Level,
-- because Shared Row Locks are not possible anymore.
BEGIN TRANSACTION SELECT * FROM Foo WITH (HOLDLOCK)
WHERE ID = 5000 SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID ROLLBACK
GO
在这个事务期间,当你查看锁管理器时,你可以看到SQL Server只在表层级获得IS所,在页层级获得共享锁,没有行级别的锁!
这些获得的锁现在没有约束,因为通常SQL Server在页层级获得IS锁,在行本身获得共享锁。当你通过一个事务修改你的数据,这个概念同样适用。
-- SQL Server acquires for an UPDATE statement an Exclusive Lock on the Page Level,
-- because Exclusive Row Locks are not possible anymore.
BEGIN TRANSACTION UPDATE Foo
SET Col2 = REPLICATE('y', 100)
WHERE ID = 5000 SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID ROLLBACK
GO
在这个情况下,最后你还是在页层级有排它锁,而不是IX锁。
停用页层级锁
接下来让我们停用页层级锁:
-- Disable Page level locks
ALTER INDEX idx_ci ON Foo REBUILD
WITH (ALLOW_PAGE_LOCKS = OFF)
GO
首先我想向你展示下索引重组操作取决于页层级锁,因此这个重组操作会失败:
The index “idx_ci” on table “Foo” cannot be reorganized because page level locking is disabled.
现在让用重新运行我们的SELECT语句,但这次使用HOLDLOCK查询提示:
-- There is no IS lock on the Page anymore.
BEGIN TRANSACTION SELECT * FROM Foo WITH (HOLDLOCK)
WHERE ID = 5000 SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID ROLLBACK
GO
当你再次查看锁管理器,你会看到在页层级IS锁消失了。我们只有在表层级IS锁,在行层级有共享锁。
让我们再来修改一条记录:
-- There is no IX lock on the Page anymore.
BEGIN TRANSACTION UPDATE Foo
SET Col2 = REPLICATE('y', 100)
WHERE ID = 5000 SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID ROLLBACK
GO
和刚才一样的事情发生了:SQL Server在表层级获得IX锁,在行上获得排它锁。在页层级没有锁……
停用行和叶层级锁
现在让我们更进一步,对于我们的具体索引停用行和页层级锁:
-- Disable Row and Page level locks
ALTER INDEX idx_ci ON Foo REBUILD
WITH (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF)
GO
现在当你读取一些数据,SQL Server只在表层级获得共享锁,你的整个表是只读的:
当你修改没有获得页和行锁的一条记录时,SQL Server在整个表上获得了排它锁——偶滴神:
小结
这篇文章的意义?为什么你应该在SQL Server里停用页和行层级锁,真的没有一个很好的理由。就用SQL Server提供的默认的锁策略即可,因为不然的话锁会约束太多,从而伤及你的性能……
感谢关注!
原文链接:
https://www.sqlpassion.at/archive/2016/10/31/disabling-row-and-page-level-locks-in-sql-server/
在SQL Serve里停用行和页层级锁的更多相关文章
- 在SQL Server里如何进行数据页级别的恢复
在SQL Server里如何进行页级别的恢复 关键词:数据页修复 在今天的文章里我想谈下每个DBA应该知道的一个重要话题:在SQL Server里如何进行页级别还原操作.假设在SQL Server里你 ...
- SQL Serve里你总要去改变的3个配置选项
你用安装向导安装了全新的SQL Server,最后你点击了完成按钮.哇噢~~~现在我们可以把我们的服务器进入生产了!抱歉,那并不是真的,因为你的全新SQL Server默认配置是错误的. 是的,你没看 ...
- SQL Serve里DBA要去改变的3个配置选项
用安装向导安装了全新的SQL Server,最后你点击了完成按钮.哇噢~~~现在我们可以把我们的服务器进入生产了! 抱歉,那并不是真的,因为你的全新SQL Server默认配置是未优化的,一个合格的D ...
- SQL Server里的自旋锁介绍
在上一篇文章里我讨论了SQL Server里的闩锁.在文章的最后我给你简单介绍了下自旋锁(Spinlock).基于那个基础,今天我会继续讨论SQL Server中的自旋锁,还有给你展示下如何对它们进行 ...
- 在SQL Server里为什么我们需要更新锁
今天我想讲解一个特别的问题,在我每次讲解SQL Server里的锁和阻塞(Locking & Blocking)都会碰到的问题:在SQL Server里,为什么我们需要更新锁?在我们讲解具体需 ...
- 在SQL Server里如何进行页级别的恢复
在今天的文章里我想谈下每个DBA应该知道的一个重要话题:在SQL Server里如何进行页级别还原操作.假设在SQL Server里你有一个损坏的页,你要从最近的数据库备份只还原有问题的页,而不是还原 ...
- SQL Server里的文件和文件组
在今天的文章里,我想谈下SQL Server里非常重要的话题:SQL Server如何处理文件的文件组.当你用CREATE DATABASE命令创建一个简单的数据库时,SQL Server为你创建2个 ...
- SQL Server里的闩锁耦合(Latch Coupling)
几年前,我写了篇关于闩锁和为什么SQL Server需要它们的文章.在今天的文章里,我想进一步谈下非缓存区闩锁(Non-Buffer Latches),还有在索引查找操作期间,SQL Server如何 ...
- 在SQL Server里我们为什么需要意向锁(Intent Locks)?
在1年前,我写了篇在SQL Server里为什么我们需要更新锁.今天我想继续这个讨论,谈下SQL Server里的意向锁,还有为什么需要它们. SQL Server里的锁层级 当我讨论SQL Serv ...
随机推荐
- 四则运算安卓客户端UI截图(部分)
1.我们组安卓手机客户端UI设计主要由林培文同学负责,界面中用到的素材全部由他一人用PS制作,所以在素材来源上当属原创啦.正因为UI由一个人设计,同时他还得分担少量后台代码的编写,颇多的工作量与人才短 ...
- eclipse创建Maven-web项目(-)
一.new----other----maven----maven project 二.next 三.next(选择maven-archetype-webapp) 四.填写相应的信息,Packaged是 ...
- Mpale 在汽车底盘悬架系统公差分析应用
汽车底盘的作用是接受发动机的动力,使车轮转动,并保证汽车按驾驶员的操纵正常行驶.底盘包括传动系统.行驶系统.转向系统和制动系统这四大部分,通常,这四大系统也简称为传动系.行驶系.转向系和制动系.悬架是 ...
- win 8 换 win7 注意事项
win8 换win7 硬盘格式修改一下gpt 格式转换为mbr模式 当进入到要选择安装到某一个盘时,由于磁盘的类型不同,会提示:“选中的磁盘采用GPT分区形式无法安装系统”.这时需要重新设置分区形式( ...
- SQLite3
记录一个基础的IOS下SQLite的例子: @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSAr ...
- Linux环境下部署完JDK后运行一个简单的Java程序
前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...
- MySQL 启动服务报错解决方案
标签:ERROR! The server quit without updating PID file (/var/lib/mysql/localhost.localdomain.pid) 概述 文章 ...
- Android开发学习之路-图片颜色获取器开发(1)
系列第一篇,从简单的开始,一步一步完成这个小项目. 颜色获取就是通过分析图片中的每个像素的颜色,来分析整个图片的主调颜色,有了主调颜色,我们可以用于图片所在卡片的背景或者标题颜色,这样整体感更加强烈. ...
- Struts2-修改数据
<body> 用户信息:<br><br> <% List<User> lu = (List<User>)request.getAttr ...
- Sql Server系列:Delete语句
数据的删除将删除表的部分或全部记录,删除时可以指定删除条件从而删除一条或多条记录.如果不指定删除条件,DELETE语句将删除表中全部的记录,清空数据表. 1 DELETE语法 [ WITH <c ...