在SQL Server数据库中,统计信息更新(UPDATE STATISTICS)会被其它会话阻塞吗?统计信息更新(UPDATE STATISTICS)会引起其它会话阻塞吗?在回答这两个问题前,我们必须搞清楚,统计信息更新这个操作期间会申请/持有那些锁。如果弄清楚了这些,那么我们就能很容易回答这两个问题了。如果要弄清楚统计信息更新会申请/持有那些锁,我们可以用SQL脚本或SQL Server Profiler工具来查询/定位相关的锁信息

SQL脚本方式

SELECT * FROM  sys.dm_tran_locks
WHERE request_session_id=xxx;  --xxx用具体的会话ID替换

SELECT resource_type ,
       resource_subtype ,
       resource_description ,
       resource_associated_entity_id ,
       request_mode ,
       request_type ,
       request_status ,
       request_session_id  
FROM sys.dm_tran_locks
WHERE request_session_id = xxx;

用SQL脚本的话,不太容易捕捉到统计信息更新(UPDATE STATISTICS)整个过程中申请的所有相关锁信息,而且小表的统计信息更新速度非常快(时间短到你来不及去查询相关锁信息,有些锁就已经申请成功,并释放了,可能统计信息更新都已经完成了),如果要实验的话,可能需要构造一个很大的表。这种方式还是有一些缺陷与不足。

SQL Server Profiler跟踪方式

使用SQL Server Profiler工具追踪更新统计信息期间会申请/持有哪一些锁。这种方式比较容易捕捉到整个过程中所有相关的锁申请与锁释放的详细信息,而且用SQL Server Profiler跟踪锁的申请与释放也非常方便。个人推荐使用这种方式。

下面我们打开一个会话窗口,找出会话ID(当前测试环境会话ID为53),然后使用SQL Server Profiler跟踪会话ID=53的锁的申请与释放(Lock:Acquired, Lock:Released),此处SQL Server Profiler的相关操作细节略过。然后在会话窗口执行下面语句

UPDATE STATISTICS  TEST WITH FULLSCAN,ALL;

如下部分截图所示,我们可以看到在统计信息更新期间,数据库会在相关对象上请求架构稳定锁(Sch-S)、架构修改锁(Sch-M)、共享锁(S),排它锁(X),意向排他锁(IX),更新锁(U)等,整个过程会有较多的锁申请与锁释放。

从上面实验可以看出,在 SQL Server 中,更新统计信息可能会申请持有很多类型的锁,那么我来一项项分析,在分析之前,我们来看一下锁的兼容矩阵,如果对这方面知识有点模糊不清的,正好可以重温一下这方面的知识点:

注意:除了架构修改锁 (Sch-M)之外,架构稳定锁 (Sch-S) 与所有锁定模式都兼容。而Sch-M 锁与所有锁定模式都不兼容。

1. 共享锁(S)

从实验数据来看,共享锁都发生在统计信息元数据对象上。这些元数据对象,如下截图所示,分别为sysschobjs和sysobjvalues,当然还有OBJECT_ID=0 OBJECTID2=xxxx的数据页或数据行。

SELECT t.object_id AS ObjectID,
       OBJECT_NAME(t.object_id) AS ObjectName,
       SUM(u.total_pages) * 8 AS Total_Reserved_kb,
       SUM(u.used_pages) * 8 AS Used_Space_kb,
       u.type_desc AS TypeDesc,
       MAX(p.rows) AS RowsCount
FROM sys.allocation_units AS u
JOIN sys.partitions AS p ON u.container_id = p.hobt_id
JOIN sys.objects AS t ON p.object_id = t.object_id
where u.allocation_unit_id=281474980642816 
GROUP BY t.object_id,
         OBJECT_NAME(t.object_id),
         u.type_desc
ORDER BY Used_Space_kb DESC,
         ObjectName;

注意:查询条件中用实际具体的OBJECTID2的值替换。

从锁的兼容性来分析的话,这时发生阻塞与被阻塞的可能性是存在的,统计信息更新期间,在申请共享锁时,某些操作在元数据对象上持有意向排他共享锁(SIX)、意向排它锁(IX)、排它锁(X),例如并发的会话跟新统计数据等操作,实际场景中,统计信息更新很少在发生申请共享锁时阻塞其它会话与被其它会话阻塞。

2. 架构稳定性锁(Sch-S)

当UPDATE STATISTICS时,SQL Server 会获取架构稳定锁(Sch-S)。这里不仅仅是统计信息更新涉及的相关对象还包括统计信息元数据对象,都会获取Sch-S锁,而对于架构稳定锁(Sch-S)有下面一些规则:

  • 允许其他会话继续读取或修改数据(如 SELECT、INSERT、UPDATE)。
  • 仅阻塞需要修改表结构的操作(如 ALTER TABLE、CREATE INDEX),因为这些操作需要架构修改锁(Sch-M),与架构稳定锁(Sch-S)不兼容。

此时,除非有并发的会话对表结构进行修改(DDL)或者并发会话在进行统计信息更新操作,此时刚好持有 Sch-M 锁,那么就可能会被阻塞。 我们会结合架构修改锁(Sch-M)构造测试案例。

3. 架构修改锁(Sch-M)

当更新统计信息时,SQL Server 会尝试获取统计信息元数据对象上的架构修改锁(Sch-M)。这种锁用于确保在更新统计信息的过程中,其他会话不会对统计信息进行修改。如果其他会话已经持有与 Sch-M 不兼容的锁(如架构稳定性锁 Sch-S),则更新统计信息的操作可能会被阻塞。

这些元数据对象,如下截图所示,分别为sysschobjs和sysobjvalues等对象。

那么我们简单构造一下统计信息更新被阻塞的案例,如下所示

--会话58中执行下面语句,模拟事务正在修改表结构(DDL),此时事务未提交/事务正在执行阶段

begin tran
alter table test add kk varchar(30);
--rollback;

--会话53中执行下面语句更新统计信息

UPDATE STATISTICS  TEST WITH FULLSCAN,ALL;

在会话窗口监控阻塞情况,如下所示,对表进行DDL操作时,会阻塞统计信息的更新,此时更新统计信息的会话的等待类型为LCK_M_SCH_S,意味着会话53正在等待获取架构稳定锁(Sch-S), 其实反过来,更新统计信息也会阻塞一些会话对相关表进行DDL操作。此时对相关表进行DDL操作时。个人也构造了另外一个大表测试案例进行了验证。有兴趣也可以验证一下。此处略过。

4. 意向排它锁(IX)与排它锁(X)与更新锁(U)

在更新统计信息时,SQL Server 还可能会对相关表(例如,sysobjvalues)中的数据行或页获取行锁(X、U 等)或页锁(IX、IU 等)。这些锁用于确保在采样数据时,数据不会被其他事务修改。如果有并发的DDL或统计信息跟新的话,也有可能导致阻塞与被阻塞。但是实际生产环境中,这种可能性非常小。另外,在表TEST进行统计信息更新时,也会在TEST上有一个短暂的排它锁(X),它的子类型(Resource subtype)为UPDSTATS,根据官方文档[1],只要子类型不同(不同的子类型彼此之间不会冲突),它是不会阻塞表上的DML操作的,除非另外一个会话也在更新统计信息。这种概率微乎其微。

此处附上官方文档的内容:

Represents a subtype of resource_type. Acquiring a subtype lock without holding a non-subtyped lock of the parent type is technically valid. Different subtypes do not conflict with each other or with the non-subtyped parent type. Not all resource types have subtypes.

结论总结

统计信息更新可能被其它会话阻塞,统计信息更新也有可能阻塞其它会话。当统计信息更新时,会获取统计信息元数据对象上的架构修改锁(Sch-M)。如果其他会话已经锁定了同一对象,或者需要在统计信息元数据对象上获取架构稳定性锁(Sch-S)来编译查询的会话,可能会被阻塞。但是这种场景比较少;另外不要同时做DDL(修改表结构、创建维护索引)和统计信息更新操作,不要并发的去做统计信息更新(很少有这种场景)。绝大部分场景下,是可以大胆地执行统计信息更新操作,它不会阻塞数据操作(DML),不用担心它阻塞了其它会话或被阻塞的。

参考资料
[1]

1: https://learn.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql?view=sql-server-ver16&redirectedfrom=MSDN

SQL Server统计信息更新会被阻塞或引起会话阻塞吗?的更多相关文章

  1. SQL Server 统计信息(Statistics)-概念,原理,应用,维护

    前言:统计信息作为sql server优化器生成执行计划的重要参考,需要数据库开发人员,数据库管理员对其有一定的理解,从而合理高效的应用,管理. 第一部分 概念 统计信息(statistics):描述 ...

  2. 全废话SQL Server统计信息(2)——统计信息基础

    接上文:http://blog.csdn.net/dba_huangzj/article/details/52835958 我想在大地上画满窗子,让所有习惯黑暗的眼睛都习惯光明--顾城<我是一个 ...

  3. 全废话SQL Server统计信息(1)——统计信息简介

    当心空无一物,它便无边无涯.树在.山在.大地在.岁月在.我在.你还要怎样更好的世界?--张晓风<我在> 为什么要写这个内容? 随着工作经历的积累,越来越感觉到,大量的关系型数据库的性能问题 ...

  4. SQL Server统计信息:问题和解决方式

    在网上看到一篇介绍使用统计信息出现的问题已经解决方式,感觉写的很全面. 在自己看的过程中顺便做了翻译. 因为本人英文水平有限,可能中间有一些错误. 假设有哪里有问题欢迎大家批评指正.建议英文好的直接看 ...

  5. SQL Server 统计信息

    SELECT * FROM SYS.stats _WA_Sys_00000009_00000062:统计对象的名称.不同的机器名称不同,自动创建的统计信息都以_WA_Sys开头,00000009表示的 ...

  6. SQL SERVER 统计信息概述(Statistics)

    前言 查询优化器使用统计信息来创建可提高查询性能的查询计划,对于大多数查询,查询优化器已经为高质量查询计划生成必要的统计信息,但是在少数情况下,您需要创建附加的统计信息或者修改查询设计以得到最佳结果. ...

  7. SQL Server 统计信息的创建与更新

    前期准备: 普通表.临时表:它两会有统计信息. 表变量:           不会有统计信息. ---------------------------------------------------- ...

  8. SQL Server 统计信息更新时采样百分比对数据预估准确性的影响

    为什么要写统计信息 最近看到园子里有人写统计信息,楼主也来凑热闹. 话说经常做数据库的,尤其是做开发的或者优化的,统计信息造成的性能问题应该说是司空见惯. 当然解决办法也并非一成不变,“一招鲜吃遍天” ...

  9. SQL Server统计信息偏差影响表联结方式案例浅析

      我们知道数据库中的统计信息的准确性是非常重要的.它会影响执行计划.一直想写一篇关于统计信息影响执行计划的相关博客,但是都卡在如何构造一个合适的例子上,所以一直拖着没有写.巧合,最近在生产环境中遇到 ...

  10. SQL Server 统计信息对查询的影响

    优化器根据开消确定选择哪个执行计划,开消又与行数统计信息有关,默认情况下统计信息是在优化的过程中自动生成的. 一旦列被标记为需要统计信息,查询优化器就会查找该列以有的统计信息,如果以有一个统计信息,下 ...

随机推荐

  1. 项目监控之sentry

    github: https://github.com/getsentry/sentry 1.什么是sentry? 当我们完成一个业务系统的上线时,总是要观察线上的运行情况,对于每一个项目,我们都没办法 ...

  2. 震惊!推荐一款AI驱动的自动化测试神器:TestCraft

    在当今快速迭代的软件开发环境中,自动化测试已经成为确保软件质量的重要一环.然而,传统的手动录制和编写测试脚本的方式不仅耗时耗力,还难以跟上敏捷开发的节奏. 本文将为大家介绍一款基于AI技术的自动化测试 ...

  3. StarBlog博客Vue前端开发笔记:(1)准备篇

    前言 之前在[基于.NetCore 开发博客项目 StarBlog - (32) 第一期完结]里说到 StarBlog 的 Vue 前端系列已经写好了 本来打算后面再发的,不过最近有点懒没去写新的文章 ...

  4. 服务拆分之《阿里云OCR使用指南》

    在做一件什么事情: 遇到了什么问题: 问题分析: 业界解决方案: 我的方案: 最终的结果: 服务都已经迁移过来了,对应的那些使用的工具什么的也都得换成自己的账号.起初原始用的是什么忘记了,时间太长了已 ...

  5. CI/CD集成规范

    集成方式说明 a.用户向Gitlab提交代码,代码中包含 Dockerfile, JenkinsFile文件. b.Jenkins监听Gitlab代码库的推送和变更事件 c.Jenkins调用mave ...

  6. win10重装如何跳过微软账号直接设置本地帐户

    ​在添加你的帐户界面,选择脱机帐户 第二个页面,选择有限的体验 第三个页面,设置自己本地的用户名 第四个页面,设置自己本地的密码

  7. java多层级zip解压

    java多层级zip解压 前言 项目中偶然需要,希望能处理嵌套的压缩包,但是又不希望把文件解压处理.原本不希望重复造轮子,但没有发现很好用的现成案例,就简单处理了一下. 正文 java做zip解压一般 ...

  8. 【Web前端】【开源分享】H5登陆界面 - 2021年12月30日

    下载地址 Gitee下载 后续更新关注本文评论区作者萌狼蓝天的回复

  9. logback 中打印自定义参数 (ip 服务名)

    打印 application.properties 配置文件中的参数 首先需要引入文件 <property resource="application.properties" ...

  10. 关于Qt国产化系统开发的几点总结

    随着国产化的兴起,各种国产系统和国产数据库等逐渐进入开发者的世界,科普几个要点. 中标麒麟neokylin基于fedora. 银河麒麟kylin早期版本比如V2基于freebsd,新版本V4.V10基 ...