SQL Server架构----查询的生命周期(上)

时间:2021-07-16 00:59:14

这里先介绍关系引擎和存储引擎、缓冲池和基本的SELECT语句的生命周期。下图所展示的高层组件将用来说明查询的生命周期。

SQL Server架构----查询的生命周期(上)

关系引擎和存储引擎

SQL Server分为两种引擎,即关系引擎和存储引擎。关系引擎有时也称作查询处理器,因为它的主要功能是查询优化和执行。它包含一个命令解析器,用来检查查询的语法,并准备查询树。查询优化器,可以说是任何数据库系统中的王冠之珠;查询执行器负责执行。

存储引擎负责管理所有的I/O数据,它包含访问方式的代码,处理行、索引、页、分配和行版本的I/O请求。缓冲管理器涉及SQL Server的主存消费者,缓冲池。它还包含一个事务管理器,用来处理数据的锁定,以保持隔离ACID属性和管理事务日志。

 

缓冲池

缓冲池是SQL Server最大的内存消耗者。它包含SQL Server中所有不同的缓存,其中包括计划缓存数据缓存,贯穿查询的生命周期。

 

基本的SELECT查询

在这个例子中使用的查询的细节并不重要, 这是一个简单的SELECT语句,没有JOIN所以你只是发出一个基本的读请求开始于客户端你所接触的第一部分是SQL Server网络接口(SNI

SQL Server网络接口(SNI),是用于建立客户端和服务器端之间网络连接的协议层。它由一组API组成,用于数据库引擎和SQL Server Native Client (SNAC)。SNI不是直接配置的,你仅仅需要配置客户端和服务器端上的网络协议。SQL Server支持如下协议:

网络协议
说明 如果值为 DISABLENETWORKPROTOCOL=1 如果值为 DISABLENETWORKPROTOCOL=0
Shared Memory 允许连接到在同一台计算机上运行的 SQL Server 实例。不能用于通过网络上的其他计算机访问。 启用 启用
TCP/IP 允许通过指定计算机名称和实例名或 IP 地址和实例名,对 SQL Server进行网路访问。 禁用 启用
Named Pipes 允许通过支持众多网络协议(包括 NetBEUI、TCP/IP 以及 IPX/SPX)对 SQL Server进行网络访问。基于客户端配置自动选择网络协议。 启用,仅用于本地 启用
虚拟接口体系结构 (VIA) 用于系统区域网络,此类网络是连接服务器或服务器群集的高速网络。不推荐使用 VIA 协议 不支持 不支持

无论使用何种网络协议,一旦连接建立SNI将会创建一个安全的连接到服务器上的一个TDS(Tabular Data Stream)端点,然后用于发送请求和接收数据。

TDS端点

微软的专有协议,用来和数据库服务器交互。当 SQL Server 数据库引擎 与应用程序通信时,它将使用称为“表格格式数据流”(TDS) 数据包的 Microsoft 通信格式来格式化通信数据。SNI协议层将 TDS 数据包封装在标准通信协议(例如,TCP/IP 或 Named Pipes)内,服务器为每个网络协议创建一个称为“TDS 端点”的 SQL Server 对象。在服务器中,TDS 端点是在 SQL Server 安装过程中由 SQL Server 安装的。对于 Named Pipes 和 Shared Memory 协议,每个实例只能有一个端点。对于这些协议类型没有可配置的端点。对于 TCP/IP 和 VIA,有默认端点,但可以创建附加端点。附加端点为仅 sysadmin 固定服务器角色的成员可以使用的专用管理员连接 (DAC) 创建。HTTP 端点也是用户创建的,它们不会显示在 SQL Server 配置管理器中。

协议层

在SQL Server中的协议层收到TDS数据包时它会逆向做SNI在客户端的工作,即解封数据包,找出包含了什么请求。协议层还负责封装结果和状态信息,并以TDS消息的形式发送回给客户端SELECT语句在TDS数据包里被标记为一个SQL命令”类型的消息,因此被传递到查询分析器,接下来传到执行器

下图显示了到目前为止查询的经过在客户端该语句SQL Server网络接口封装在一个TDS数据包里,并将其发送到SQL Server上的协议层,然后在协议层解封并被确认为一个SQL命令,代码被SNI发送到命令解析器代码。

 SQL Server架构----查询的生命周期(上)

 命令解析器


用于处理T-SQL语言事件,它首先检查语法,将任何错误返回到协议层,再传送到客户端。如果语法有效,那么下一步就是生成查询计划或者找到现有的计划。查询计划包含SQL Server如何执行一段代码的详细信息,这通常称为执行计划。

为检查查询计划,命令解析器会生成T-SQL的哈希值,并针对计划缓存检查,来确定是否已存在一个合适的计划。计划缓存区是缓冲池中的一个区域,用于缓存查询计划。如果找到匹配的,那么这个计划将从缓存中被读取出来,然后传递给查询执行器执行。

计划缓存区

创建执行计划可能很耗时耗资源,因此,如果SQL Server已经找到执行一段代码的好方法,就应该尝试让后续的请求重用它。如果没有找到匹配的计划,命令解析器就会基于T-SQL生成一个查询树,查询树的每个节点都代表查询中的一个需要执行的操作。这棵树,然后传递给查询优化器来处理我们的基本查询没有这么一个查询树被创建并传递给查询优化现有计划

下图展示了到目前为止查询的处理经过。

SQL Server架构----查询的生命周期(上)

 

查询优化器

查询优化器被SQL Server团队视为珍贵的财产,是产品中最复杂和隐秘的部分。它是“基于成本”的优化器,这意味着要评估多种执行方法,并选择其中成本最低的方法来执行。执行方法”被视为一个查询计划,并查询优化器输出。实际上,优化器的任务是在合理的时间里找到好的计划,而不是最好的计划。优化器的目标是找到最有效的计划。

除了基于成本,优化器还执行多级优化,每级优化中找到好的计划后就进入下一阶段。首先是预优化阶段,当查询语句简单到仅有一个最优方案时就会退出处理。下一阶段是优化的实际处理,其又分为3个小阶段。第一个小阶段,优化器会着眼于嵌套循环连接,它不考虑并行运算符,当发现计划的成本<0.2时就会停止,这个阶段生成的计划被称为事务处理(TP)计划。第二个小阶段,优化器使用可能的优化规则的一个子集,并寻找已经有一个计划的通用模式,成本<1.0时就会停止,这个阶段生成的计划被称为快速的计划。第三个,也就是最后一个阶段,优化器会使用所有的优化规则,还会考虑并行和索引视图,该阶段创建的计划具有一个优化级别“全(Full)”。以上说的成本,是根据操作符的基准值算出的,与硬件的好坏无关。

 

查询执行器

查询执行器的工作不言自明,就是用来执行查询的。更确切地说,是执行查询计划,并于存储引擎交互以检索或修改数据。它对存储引擎的接口实际上是OLE DB

下图显示了优化器生成的查询计划传送到执行器,执行器通过OLE DB接口与存储引擎交互。

SQL Server架构----查询的生命周期(上)

访问方法

访问方法是代码的集合,它为数据、索引,以及用于检索修改数据的接口提供存储结构。包含了检索数据的所有代码,但它实际上并不执行该操作本身,它将该请求传递
缓冲区管理器

 

缓冲区管理器

缓冲区管理器用来管理缓冲池,它代表着SQL Server的大部分内存使用。如果你要读取一个页的某些行,Buffer Manager会检查缓冲池里的数据缓存,看是否存在该页,存在的话就将结果传回Access Methods;如果不存在,Buffer Manager会从磁盘的数据库获取页,并将其放入数据缓存,然后将结果回传给Access Methods。PAGEIOLATCH等待类型表示把一个数据页从磁盘读取到内存所花费的时间。换回结果集之前,首先要把数据从磁盘读取到内存,因此,SQL Server要在内存里维持一个最低水平的可用页,否则,如果缓存里没有空间事先把新数据存放进来,你就不能够读取任何新数据。

 

数据缓存

数据缓存通常是缓冲池中最大的一块,因此,也是SQL Server最大的内存消耗者。每个数据页在使用前,都会先从磁盘读取到数据缓存。

 你可以通过DMV sys.dm_os_buffer_descriptors 来查看每个数据库在数据缓存中使用了多大空间:

SELECT CASE database_id WHEN 32767 THEN 'ResourceDb' ELSE db_name(database_id) END AS 'Database'
,count(*)*8/1024 AS 'Cached Size (MB)'
FROM sys.dm_os_buffer_descriptors
GROUP BY db_name(database_id),database_id
ORDER BY 'Cached Size (MB)' DESC


SQL Server架构----查询的生命周期(上)

 缓存中每个页面的头都存放着最后两次被访问的细节,通过定期扫描缓存来检查这些值。如果一段时间内,该页面没被访问,计数器的值就会递减,当SQL Server需要释放一些缓存时,计数器最低的哪些页面将率先被刷新。

你可以通过计数器Buffer Manager\Page Life Expectancy来查看SQL Server希望页在缓存中存放多久。

SQL Server架构----查询的生命周期(上)

 

 

基本的SELECT语句的生命周期总结:

  1. 客户端的SQL Server网络接口(SNI)通过网络协议,如TCP/IP,建立一条到服务器端SNI的连接,然后在TCP/IP连接上建立一条到TDS端点的连接,然后将SELECT语句以TDS消息的形式发送到SQL Server;
  2. SQL Server上的SNI解封TDS消息,读取SELECT语句,并传一条“SQL命令”到命令解析器;
  3. 命令解析器检查缓存池中的计划缓存,看是否存在匹配的查询计划。如果不存在,它会基于SELECT语句创建一个查询树,并将其传给优化器来生成一个查询计划;
  4. 优化器会在预优化阶段生成“零成本”或“微不足道”的计划,因为语句太过于简单。这个被创建的查询计划之后会被传送到查询执行器执行;
  5. 执行时,查询执行器要确保读取到所需的数据以完成查询计划,因此,它会通过OLE DB接口把请求传送到存储引擎里的访问方法;
  6. 访问方法需要从数据库中读取页面来完成来自查询执行器的请求,因此,它会请求Buffer Manager提供数据页;
  7. Buffer Manager检查数据缓存,看缓存中是否已存在该页面。如果不存在,它就会从磁盘里拉取页面并放入缓存,然后传回Access Methods;
  8. 最后,访问方法将结果集传回到关系引擎,进而发送到客户端。

SQL Server架构----查询的生命周期(上)