SQLServer(top)中执行计划缓存的分析

SQLServer(top)中执行计划缓存的分析
简介

SQL语句我们通常写在本质上就是获取数据的逻辑,而不是数据的物理路径。当我们写SQL语句的SQL服务器,查询分析器将解析语句反过来(解析),绑定(绑定),查询优化(优化有时被称为简化)执行(执行)。除了执行步骤、执行计划后的前三个步骤生成。也就是说,SQL Server根据计划获取物理数据,最后根据执行计划执行查询,得到查询结果,但查询优化器并不是本文的重点。本文主要描述了在执行计划生成后执行计划中cache优化器的相关机制和常见问题。

为什么需要执行计划缓存

介绍中,我们知道生成执行计划的流程步骤占了很大的比例,消耗了所有的CPU和内存资源。实际上,查询优化器生成一个执行计划来完成更多的工作,它分为3部分:

首先,根据传入查询语句的文本,对表的名称、存储过程的名称、视图名称等进行解析,然后根据逻辑数据操作生成表示查询文本的树。
第二步是优化和简化,例如,将子查询转换为对等连接,优先过滤条件删除不必要的连接(例如索引,或者不引用原始表)。
第三步是基于数据库中的统计信息来评估基于成本的(基于成本的)。
当以上三个步骤完成后,多个候选执行计划的产生。虽然我们的SQL逻辑只有一个,但在物理访问该数据序列按照逻辑顺序,例如可以不止一个,,你想从北京到上海,可以做高铁,也可以从北京到上海做飞机,但这个描述是有很多方法来实现具体的逻辑描述。让我们在SQL Server中看一个例子,如代码清单1中的查询。
*选择
从内连接对智力注
内部联接C C.C = A.
代码清单1。

此查询,无论B或B加入内一个内连接到C,结果都是一样的,所以你可以生成多个执行计划,但是一个基本原则是,SQL Server也不一定会选择最佳的执行计划,但计划是好的,这是由于消费的所有评估计划的成本不应太大。最后,根据SQL Server数据库和CPU和IO消耗每一步估算成本计划成本,所以执行计划的选择在很大程度上依赖于统计信息、统计信息的相关内容,我就不细说了。

不难看出,产生以前的查询分析器执行计划的过程中不难看出,和资源的成本是惊人的。因此,当相同的查询被执行一次,缓存将大大减少执行计划的编制和提高效率,这是原来的执行计划缓存的意图。

执行计划缓存的对象

执行计划中缓存的对象分为4类:

编制:编制计划执行计划和执行计划是MSIL和C #关系相同的关系。
执行上下文:在编译计划的执行中会有一个上下文,因为编译计划可以由许多用户共享,但是查询需要存储集合信息和本地变量的值。因此,上下文环境需要与执行计划相关,执行上下文也称为可执行计划。
游标:存储的游标状态类似于执行上下文和编译计划之间的关系。游标本身只能由某个连接使用,但与游标相关的执行计划可以由多个用户共享。
代数:代数树树(也称解析树)代表查询文本。正如我们之前所说的,查询分析器不直接参考查询的文本,但代数树。也许你在这里有一个问题,代数树来生成执行计划,这是缓存的代数的树干。这是因为视图,默认情况下,约束可能由不同的查询利用,以及这些对象的代数树缓存保存解析过程。
例如,我们可以利用dm_exec_cached_plans DMV找到缓存的执行计划,如图1所示。
图1。要缓存的执行计划

这些类型的对象缓存所占用的内存相关信息又如何呢我们可以看到通过dm_os_memory_cache_counters DMV,缓存对象的上述类如图2所示。
图2。内存中这些类对象缓存占用的内存

此外,执行计划缓存是一种缓存。缓存中的对象是由算法所取代。执行计划缓存替换算法主要是基于内存的压力,记忆的压力分为两种,内部和外部的压力,外部压力是由于缓冲区池中的可用空间降低到某一临界值。阈值将根据物理内存的大小而变化。如果设置了最大内存,它将基于最大内存。内部压力是由于执行计划缓存中的对象超过某个阈值的事实,例如,32位SQL Server的阈值为40000,而64位值被提升为160000。

这里的重点,缓存标识符查询本身,所以选择*选择* schemaname.tablename字段虽然效果是一致的,但需要缓存两执行计划,所以最好的做法是在参考表名和其他名称等,请将模式名称。

基于缓存执行计划的语句调优

存储在高速缓存执行计划的内容十分丰富,不仅包括缓存执行计划表,又例如缓存执行计划,统计信息,使用和CPU的等待时间。但值得注意的是,这里的数据是唯一的执行时间,而不是编译的时间。例如,我们可以使用代码在清单2的代码在数据库中查找最长20的查询语句,根据缓存的执行计划。
设置事务隔离级别
选择前20
铸造(qs.total_elapsed_time / 1000000为十进制(28, 2))
{总持续时间(})
铸造(qs.total_worker_time * 100 / QS。total_elapsed_time)
作为十进制(28, 2))
铸造((qs.total_elapsed_time QS。total_worker_time)* 100 /
qs.total_elapsed_time为十进制(28, 2)){等}为%
qs.execution_count
铸造(qs.total_elapsed_time / 1000000 / QS。execution_count)
作为十进制(28, 2)作为{平均持续时间(})}
子串(qt.text,(QS。statement_start_offset / 2)+ 1,
(当qs.statement_end_offset = - 1
然后,len(转换(nvarchar(max)、QT。文本)×2
其他qs.statement_end_offset
端QS。statement_start_offset) / 2)+ 1)为{个人查询
qt.text作为家长查询} {
db_name(QT。DBID)作为数据库
qp.query_plan
从sys.dm_exec_query_stats QS
交叉应用sys.dm_exec_sql_text(QS。sql_handle)QT
交叉应用sys.dm_exec_query_plan(QS。plan_handle)QP
在qs.total_elapsed_time > 0
通过qs.total_elapsed_time倒序
代码清单2。通过执行计划缓存,查找具有耗时最长的数据库的20个查询语句

以上声明你可以根据不同的条件修改订单,希望找到你所希望的语句,没有详细资料。

无论是微量或探查客户服务器相比,这种方法具有一定的优势,如果通过捕获跟踪分析,不仅费时费力,而且还带来额外开销的服务器,通过查找耗时的查询将更简单的方法。但统计数据只在最后的实例重新启动或没有运行DBCC freeproccache但该方法也有一些缺点,如:

像索引重建和更新统计之类的语句没有缓存,这些语句的成本非常高。

缓存可能在任何时间被替换,因此该方法不能看到缓存中的语句。

统计信息只能看到执行成本,无法看到编译成本。

没有参数化缓存可能会为同一语句提供不同的执行计划,因此出现不同的缓存。在这种情况下,不能积累统计信息,这可能不是很准确。
执行计划缓存与查询优化器之间的矛盾

还记得我们之前说的,编译并选择执行计划分为三个步骤,第一两步根据查询表,在方案选择阶段的实施对象的元数据在很大程度上依赖于统计信息,因此同样的声明不仅是相同的参数,查询优化器会为例产生不同的执行计划,我们看一个简单的例子,如图3所示。
图3。只因为参数不同,查询优化器选择不同的执行计划。

您可能会觉得这不太好,这取决于生成不同执行计划的参数。如果上述查询放置在存储过程中,则不能直接对参数进行嗅探。当第一个执行计划被缓存时,第二个执行将重用第一个执行计划。虽然编译时间被删除,但是坏的执行计划的代价会更高。让我们看看这个例子,如图4所示。

图4。不同的参数是完全相同的执行计划!
让我们看一下同一个例子,并颠倒执行顺序,如图5所示。
图5。执行计划完全改变了。

我们看到,第二执行语句完全重用第一执行计划。总是会有一个搜索的牺牲。例如,当参数为4,将有超过5000。当索引被扫描时,它应该是最有效的。但是图4重用了最后一个执行计划,并用了5000次找到它!!!这无疑是低效的,这种情况对于DBA来说是非常混乱的,因为缓存中的执行计划是不可控的,缓存中的对象随时都可能被删除。那些首先执行性能问题的人常常会使DBA头疼。

从这个示例中,我们可以看到查询优化器希望尽可能地选择高效的执行计划,而执行计划缓存则希望尽可能多地重用缓存。这两种机制在某些情况下会发生冲突。

在下一篇文章中,我们将继续看到执行计划缓存和查询分析器之间的冲突,以及编译器执行计划的常见问题和解决方案。

总结

在这篇文章中,我们简单地描述为查询优化器的执行计划的过程,以及执行计划缓存机制。一些问题出现时,查询优化器的执行计划缓存相交在一个糟糕的情况。在下一篇文章中,我们将继续探索的执行计划的SQL Server缓存。

以上是SQL Server中的执行计划缓存(top)的完整描述,这是介绍给您的。希望你能喜欢。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部