SQL执行计划解析之执行计划基础上篇

执行计划,简单的说就是查询优化器计算的结果,表示执行被提交查询的效率***的方式。执行计划告诉你查询是如何被执行的,因此它是DBA诊断低性能查询的基础手段。

1.查询提交后发生了什么

当查询被提交到Sql Server DataBase之后,很多过程就开始工作,最终目的是将数据尽快返回给用户或者存储起来,同时保持数据的一致性。这些过程为每个提交到服务器的查询服务,因而有很多的不同的动作同时发生在服务器上,我们只关注T-SQL相关的事情,粗略的分为两个阶段:

  • 关系引擎(relational engine)中发生的过程
  • 存储引擎(storage engine)中发生的过程

在关系引擎中,查询优化器解析和处理查询,产生执行计划,然后执行计划被送到存储引擎(二进制方式),存储引擎使用执行计划来获取或更新数据。锁定、索引维护、事物等都发生在存储引擎里头。由于执行计划是由关系引擎产生的,我们将主要关注关系引擎。

1.1查询解析

T-sql查询到达服务器后去的***个地方就是关系引擎,它被传递给一个进程来检查拼写和形式,这个处理进程就是查询解析过程。解析过程的输出是一个解析树。解析树代表了执行查询的逻辑步骤。如果T-sql语句不是一个数据操纵语言(DML)声明就不会被优化,举个例子,对于创建table,系统只有一种“正确”的方式,那么就没有机会来提升性能。如果T-sql是DML声明,解析树就被传递给一个叫algebrizer的进程,algebrizer解析查询引用到的所有的对象、表、列的名字,并且识别列的类型(varchar(50) vs nvarchar(25)等),除此之外还要执行一个叫做聚合绑定 的过程来决定聚合的位置。algebrizer进程很重要,因为查询里可能包或了别名、同义词或者不存在的名字,这些需要被解析,或者查询引用了不存在的对象。algebrizer的输出是query processsor tree,二进制形式,然后被传递给了查询优化器。

1.2查询优化器

查询优化器决定了数据能否访问索引、使用哪种连接还有其他很多东西。这种决定是基于开销的,所需的cpu、io等。查询优化器将会产生并评估很多的计划(除非cache里已经有了),一般来说,选择开销***的那个,比如运行最快,使用最少的资源、cpu、I/O的那个。执行速度仍然是最重要的因素,如果能够更快返回结果,优化器会选择cpu密集型的过程。有时候优化器也会选择效率较低的计划,如果它认为花时间去评估很多的执行计划还不如采用较低效率的过程。如果你提交了一个非常简单的查询,比方说,单表查询、没有索引、没有聚合、没有计算,那么优化器就不会花时间来计算优化,而是简单的使用trival plan。

如果查询是非Trival的,那么优化器就会计算开销然后选择一个计划。因此它需要依赖sql server服务器维护的统计数据。统计数据是数据库收集的关于列和索引的数据,它描述了数据的分布(distribution)、唯一性(uniqueness)和选择性(selectivity)。构成统计数据的信息使用一个直方图(histogram)和表格(tabulation)来表示,它是从200个平均分布的数据点(data Points)取出来的表示特定数据的出现次数。这种“关于数据的数据”给优化器提供了计算所需的必要信息。

如果列和索引相关的统计数据存在,那么优化器就会使用它们来计算。缺省地,系统会为所有索引和那些用作谓词(predicate)、where子句的一部分、join on子句的一部分的列创建和更新统计数据。Table变量不会产生统计数据,优化器始终假定它只有一行而无视它真正的大小。临时表有统计数据,和***表的统计数据存储在同一个直方图里供优化器使用。

优化器使用这些统计数据和query processor tree一起决定***的执行计划。这就意味着,它需要测试一系列的计划,测试不同的join类型,组织join的顺序,尝试不同的索引等等,直到达成它认为的最快的执行计划。在这个计算中,每一步都赋予了一个数值,代表了优化器预估的时间开销(estimated cost),每一步的开销加起来就是执行计划的开销。

有必要指出,预估的开销毕竟是预估的,如果有无限的时间和完整的***的统计数据,优化器就能找到执行查询的***计划,但是优化器是试图在最短的时间找到***的执行计划,并且明显的,可用的统计数据的质量也是有限的,因此,虽然这个开销估算是个非常有用的手段,但是不能精确的反映现实。

优化器决定执行计划后,实际的执行计划就被创建并且存储进内存空间plan cache,除非相同的执行计划cache里已经存在。优化器产生可能的执行计划(potential plans),和cache里边已经存在的进行比较,如果匹配就是用cache里边的那个。

1.3查询执行

执行计划产生后,操作就转移到了存储引擎,在这里根据执行计划实际执行查询。这里不再详细讨论,除了一点,千辛万苦生成的执行计划和设计执行的可能并不一样,比方说一下情景:

  • 执行计划超出了并行执行(parallel execution)的界限
    • parallel execution 利用多处理器提高执行效率
  • 统计数据过期或者发生了改变

1.4预估的和实际的执行计划

如前所述,有两种不同的执行计划,***个是由优化器产生的预估的执行计划(Estimated execution plan),操作符和步骤被贴了Logical标签,代表了优化器的观点,另一个是实际的执行计划(Actual execution plan),代表了实际发生的事情。

1.5重用执行计划

服务器产生执行计划开销是昂贵的,可能的情况下Sql Server会尽量保持和重用执行计划。执行计划生成后就被存储进内存Plan Cache。

执行计划并不是***驻留内存,它们会慢慢地根据age变化从系统消失,age的计算公式为执行计划的预估开销*被使用的次数,例如一个计划它的开销是10,被引用了5次,那么它的age值就是50。延迟写入(lazywriter)进程负责释放所有类型的cache(包括plan cache),它周期性地扫描cache里的对象,并每次减去一定的age值。如果达到下列条件,执行计划将会从内从中被清除:

  1. 系统需要更多内存
  2. age值达到了0
  3. 执行计划没有被任何连接(connection)所引用

执行计划也不是不可改变的,有些事件或动作会迫使执行计划重新编译。记住这些很重要,因为重新编译执行计划的开销可能非常大,下面的动作会导致执行计划重新编译:

  1. 改变查询中引用的表的结构或schema
  2. 改变了查询中用到的索引
  3. 删除了查询中用到的索引
  4. 更新了查询用到的统计数据
  5. 调用了函数sp_recompile
  6. 对查询用到的表的keys进行了大量insert或delete操作
  7. 对带有触发器的表,因inserted和deleted导致的明显增长
  8. 一个查询中混合了ddl和dml
  9. 查询执行中改变了SET选项
  10. 改变了查询使用的临时表的结构或schema
  11. 改变了查询中用到的动态试图(dynamic views)
  12. 改变了查询中的游标选项
  13. 改变了远程行集,就像在分布式分割试图(distributed partitioned view)里边
  14. 使用客户端游标时,改变了FOR BROWSE选项

1.6为何预估和实际的执行计划可能不同

一般情况下,你看到的预估执行计划和实际执行计划很可能是一样的,然而当环境改变时可能会导致二者的不同。

  • 陈旧的统计数据
    • 统计数据和实际数据间的差异是导致两个执行计划不同的主要原因。通常发生在有数据插入和删除,改变了索引的键值以及分布。
    • 为了降低操作成本,原子性的统计数据操作是取样于数据的子集。这就意味着,随着时间推移,统计数据就越来越不能准确反映实际数据。
    • 这不仅会导致两个执行计划间的差异,还会导致产生“坏”的执行计划。
  • 非法的预估执行计划
    • 某些情况下,预估的执行计划根本无法工作,比如下边的例子:
      1. CREATE TABLE TempTable 
      2. Id INT IDENTITY(1, 1) 
      3. ,Dsc NVARCHAR(50) 
      4. ); 
      5. INSERT INTO TempTable ( Dsc ) 
      6. SELECT [Name
      7. FROM [Sales].[Store]; 
      8. SELECT * 
      9. FROM TempTable; 
      10. DROP TABLE TempTable; 
    • 你会得到一个错误
      1. Msg 208, Level 16, State 1, Line 7 
      2. Invalid object name 'TempTable'
    • 优化器用于产生预估的执行计划,并不执行那个T-Sql。当通过algebrizer来运行声明的时候,由于查询并没有被执行,临时表并不存在,这就会导致错误。
  • 请求并行计算
    • 计划遇到并行计算的瓶颈时,会创建两个计划,实际执行哪个取决于查询引擎。所以你可能在预估执行计划里看到有(或没有)并行操作符。当计划实际被执行时,
    • 查询引擎决定了要么它不支持并行计算或者调用并行查询后,你可能看到一个完全不同的计划。

1.7执行计划的格式

  1. 图形方式
  2. 文本方式
    1. SHOWPLAN_ALL 
    2. SHOWPLAN_TEXT 
    3. STATISTICS PROFILE 
  3. Xml方式
    1. SHOWPLAN_XML 
    2. STATISTICS_XML 

原文链接:

 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/285705.html<

(0)
管理的头像管理
上一篇2025-05-15 00:31
下一篇 2025-05-15 00:32

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注