参数化(一):计划缓存

  简介

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

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

     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个设置选项是否相同。

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

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

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

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

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

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

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PPV课数据科学社区

你用了吗?DBA必备的15款MySQL管理工具

如今,Web应用程序的响应速度是成功的关键法宝之一。它与用户互动,用户对网站的看法,甚至谷歌网站排名情况都有着密不可分的关系。数据库性能是响应速度最重要的因素之...

794110
来自专栏Netkiller

数据库进程间通信解决方案之MQ

摘要 你是否想过当数据库中的数据发生变化的时候出发某种操作?但因数据无法与其他进程通信(传递信号)让你放弃,而改用每隔一段时间查询一次数据变化的方法?下面的插件...

33840
来自专栏沃趣科技

初相识 | 全方位认识 sys 系统库

前阵子,我们的"全方位认识performance_schema"系列为大家完整的介绍了performance_schema系统库。在我们的发布计划中为什么要把p...

23730
来自专栏网络研发技术

如何防订单重复提交策略方法

#### [原文链接:https://www.cnblogs.com/jett010/articles/9056567.html](https://www.cn...

40500
来自专栏性能与架构

Mysql 压力测试工具 mysqlslap

mysqlslap 是 Mysql 自带的压力测试工具,可以模拟出大量客户端同时操作数据库的情况,通过结果信息来了解数据库的性能状况 mysqlslap 的一个...

75550
来自专栏铭毅天下

干货 | Elasticsearch索引生命周期管理探索

Elasticsearch上海Meetup中ebay工程师提了索引生命周期管理的概念。的确,在Demo级别的验证阶段我们数据量比较小,不太需要关注索引的生命周期...

31220
来自专栏数据库

游戏用户中心开发

用户中心最主要的功能就是管理用户的注册和登陆,登陆成功之后生成对应的token,并负责token的验证。当一个用户注册或登陆成功之后,它的信息会在用户中心服务中...

21080
来自专栏PHP在线

优化 MySQL: 3 个简单的小调整

如果你不改变 MySQL 的缺省配置,你的服务器的性能就像题图的坏在一档的法拉利一样 “虎落平阳被犬欺” … 我并不期望成为一个专家级的 DBA,但是,在我优化...

28770
来自专栏闵开慧

mysql性能调优

mysql调优思路: 1.数据库设计与规划--以后再修该很麻烦,估计数据量,使用什么存储引擎  2.数据的应用--怎样取数据,sql语句的优化  3.mysql...

41550
来自专栏一“技”之长

iOS调用系统通讯录 原

上一篇博客详细介绍了在IOS开发中,我们如何获取通讯录联系人的信息,即对其进行增删改查的操作:http://my.oschina.net/u/2340880/b...

10220

扫码关注云+社区

领取腾讯云代金券