参数化(一):计划缓存

参数化(一):计划缓存

  简介

  很多时候,当我执行查询调优的时候,引发查询性能糟糕的问题一般都是与参数化相关的。一方面,参数化是查询处理器核心的基本主题。它能显著影响查询性能。另一方面,大家很少对这一主题进行详尽的了解。  

  因此我准备写一个系列的随笔来介绍关于参数化的问题。第一篇我将介绍关于计划缓存的内容。为了理解参数化,有必要先理解理解执行计划如何被缓存。

     SQLServer保留一定数量的内存来保存执行计划缓存。这就是执行计划(和一下其他结构)被缓存为了未来重用的地方。查询(或语句)和批处理之间的区别时会引发混淆。前者是作为一个原子一次执行一个查询的单一命令。后者是一个被解析、简化、优化、编译并最终被执行的单位,包含多个语句。这个单位为优化器生成一个执行计划,因此执行计划缓存存储执行计划,每一个代表一个批处理。

     使用sys.dm_exec_cached_plansDMV可以查看执行计划缓存的内容。如果你打算看批处理文档和计划XML,那么可以使用下面的查询:

SELECT
	BatchText			= BatchTexts.text ,
	QueryPlan			= BatchPlans.query_plan ,
	ExecutionCount		= CachedPlans.usecounts ,
	ObjectType			= CachedPlans.objtype ,
	Size_KB				= CachedPlans.size_in_bytes / 1024
FROM
	sys.dm_exec_cached_plans AS CachedPlans
CROSS APPLY
	sys.dm_exec_query_plan (plan_handle) AS BatchPlans
CROSS APPLY
	sys.dm_exec_sql_text (plan_handle) AS BatchTexts;

 

    当查询处理器遇到一个批处理时,首先检查是否在缓存中已经有能被重用的计划。这是因为分析和编译批处理的成本是相当昂贵的。如果已经有了这个精确的执行计划,那么能节省大量的资源和时间。查询处理器如何查询批处理是否在缓存中的那?当一个新的批处理产生,它的哈希值被计算并且与已经在缓存中的执行计划比较。假如匹配的到,批处理文档按顺序去验证这的确是相同的批处理(这是因为多重文档值可能结果是相同的哈希值)。

     一些其他元素也需要被比较,例如ANSI_NULLS 和ARITHABORT等选项。有几个类似的设置选项会影响当前会话中的查询如何被执行。两个会话执行完全相同的批处理,使用不同的设置选项可能会产生不同的结果并且这就是为什么必须去通过不同的油画过程和产生不同的执行计划。因此当查询处理器发现一个计划在缓存中,它需要比较这7个设置选项是否相同。

     如果没有匹配上,则需要经过解析、简化、油画、和编译计划等过程。新产生的计划将被放到内存中为将来使用(多数情况)。

    一旦查询处理器发现缓存中有一个执行计划,它仍然会验证执行计划是否仍然可用。例如,潜在的表和索引的架构已经在计划生成后发生了变化,或许新的列被加入表中,或者索引被删除…;另外一个原因统计信息过期。如果计划基于统计信息生成的,就会被标记过期(表的大量变动)。这些都会导致新的执行计划无效。

    如果计划是有效的,查询处理器最终能执行它。整个过程看起来很长,但是实际上是非常快。如果计划无效,那么就会触发重现编译事件。这意味着再次进行批处理优化,然后新的执行计划被生成、放置在原来无效的缓存内存中。重编译已经存在的计划比编译新的要快。因为它没必有解析和简化步骤。

 

这里有一个图来总结这一过程

Plan Caching

 

    一般来说,你的目标是提高计划重用率。越是重用的多意味在编译相同执行计划时越少的资源被浪费,批处理更高效、性能更好。

    现在请看下面这个类似的执行查询应用:

SELECT
	OrderId ,
	OrderDate ,
	OrderAmount ,
	OrderStatus
FROM
	Sales.Orders
WHERE
	CustomerId = 73922;

 

    如果查询一秒内不执行50次,每次有不同顾客ID,那么这个计划缓存将很快爆炸。每个查询用不同的用户将被当做新的批处理(因为查询的哈希值在缓存中找不到),并且将必须经历整个解析–优化的处理过程。除此之外,每一个计划一定要放到内存中,因此大量内存分配活动在幕后进行。既然内存有限,有大量的计划存储。计划缓存将增加大量数据缓存,因此更少的数据也存储在缓存中,并且内存管理器将必须移除旧的计划缓存以便去有更多的空间为新的计划。

     这就是参数化扮演重要的角色。下一章将介绍执行查询的七种方式。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119729.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql—如何获取有性能问题的sql

    mysql—如何获取有性能问题的sql

    2020年11月12日
  • 一个示例让你明白适配器模式

    一个示例让你明白适配器模式本文讨论适配器模式。适配器模式是23中设计模式之一,它的主要作用是在新接口和老接口之间进行适配。它非常像我们出国旅行时带的电源转换器。为了举这个例子,我还特意去京东上搜了一下电源转换器,确实看到了很多地方的标准不一样。我们国家的电器使用普通的扁平两项或三项插头,而去外国的话,使用的标准就不一样了,比如德国,使用的是德国标准,是两项圆头的插头。

    2022年7月25日
  • python进入文件目录 命令_python创建目录

    python进入文件目录 命令_python创建目录python进入到指定目录下的方法:Python可以使用os.chdir()方法转到指定目录。os.chdir()方法用于改变当前工作目录到指定的路径。chdir()方法语法格式如下:os.chdir(path)参数path–要切换到的新路径。实例以下实例演示了chdir()方法的使用:#!/usr/bin/python#-*-coding:UTF-8-*-importos,…

    2022年8月31日
  • idc机房设施运维_软件运维需要掌握的知识

    idc机房设施运维_软件运维需要掌握的知识机房的服务器的维护是机房运维工作的重点,合理的机房环境对于服务器来说是非常的重要的,随着这年经济的发展,机房也在不断的在很多的方面进行调整,今天我们学习IDC机房服务器运维基础知识。1、关于电力(1)定期检测机房内市电及UPS电源是否稳定,并做好记录,UPS巡检记录要落实到个人。确保服务器硬件系统的稳定运转,确保市电中断后服务器正常运转理论值8小时。(2)若遇市电中断,如无特殊事宜,请尽量…

    2022年9月5日
  • 超多淘宝京东抢购秒杀软,脚本,易语言软,有作者

    超多淘宝京东抢购秒杀软,脚本,易语言软,有作者抢购软件主页进行下载,欢迎交流

    2022年5月18日
  • VMware虚拟机上网问题

    VMware虚拟机上网问题最近我遇到很多朋友在问我vmwareworkstation版本虚拟机的上网问题,在这里,我就针对这个问题做一些说明。为了朋友们更好的理解VMwareWorkstation版本虚拟机是如何连接网络的,下面我就对VMware的3种网络模型做一下相关的介绍。1.首先,介绍一下VMware的几个虚拟的网络设备:VMnet0:在桥接模式下的虚拟交换机VMnet1:在Hos

    2022年5月12日

发表回复

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

关注全栈程序员社区公众号