设为首页 收藏本站
查看: 1110|回复: 0

[经验分享] 在SQL Serve里停用行和页层级锁

[复制链接]

尚未签到

发表于 2017-7-14 15:17:38 | 显示全部楼层 |阅读模式
  今天我想谈下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所,在页层级获得共享锁,没有行级别的锁!
DSC0000.png

  这些获得的锁现在没有约束,因为通常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锁,在行层级有共享锁。
   DSC0001.png
  让我们再来修改一条记录:



-- 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锁,在行上获得排它锁。在页层级没有锁……
DSC0002.png


停用行和叶层级锁
  现在让我们更进一步,对于我们的具体索引停用行和页层级锁:



-- 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只在表层级获得共享锁,你的整个表是只读的:
DSC0003.png

  当你修改没有获得页和行锁的一条记录时,SQL Server在整个表上获得了排它锁——偶滴神:
DSC0004.png


小结
  这篇文章的意义?为什么你应该在SQL Server里停用页和行层级锁,真的没有一个很好的理由。就用SQL  Server提供的默认的锁策略即可,因为不然的话锁会约束太多,从而伤及你的性能……
  感谢关注!

原文链接:
  https://www.sqlpassion.at/archive/2016/10/31/disabling-row-and-page-level-locks-in-sql-server/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393823-1-1.html 上篇帖子: T- SQL性能优化详解 下篇帖子: 一些内存使用错误理解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表