sqLSERVER 计划缓存
在这一期的性能调优培训里,我想详细谈下SQL Server里计划缓存及其副作用。在上一周你已经学到,每个提交给SQL Server的逻辑查询会编译成物理执行计划。那个执行计划然后会被缓存,即被称为计划缓存,用作后期的重用。首先我们来看下即席SQL语句(adhoc SQL statements,对应的反义词:prepared SQL statements)的副作用,即带来的性能问题。
即席SQL语句(adhoc SQL statements)
每次当你提交一个即席SQL语句到SQL Server时,对每个唯一的查询,都会有执行计划被编译。“唯一的查询”是什么意思?答案很简单:SQL Server对完整的SQL语句(包括可能硬编码的参数值)生成一个hash值,并使用这个hash值作为在计划缓存里查找值。如果找到这个值的执行计划,这个计划就会被重用,否则的话新的计划会被编译并最后在计划缓存里缓存。看下我们提交下面这3个查询给SQL Server:

1 SELECT * FROM Sales.SalesOrderHeader
2
3 WHERE CustomerID = 11000
4
5 GO
6
7 SELECT * FROM Sales.SalesOrderHeader
8
9 WHERE CustomerID = 30052
10
11 GO
12
13 SELECT * FROM Sales.SalesOrderHeader
14
15 WHERE CustomerID = 11223
16
17 GO

对这3个查询,SQL Server会编译3个不同的执行计划,因为你提供硬编码的参数值。因此计算出来的hash值在3个查询之间是不同的,找不到被缓存的计划。作为一个副作用,对于几乎相同的查询,你有3个执行计划。这个问题被称为计划缓存污染(Plan Cache Pollution) 。
你用不同的执行计划污染了你的计划缓存,这些计划是不能被重用的(因为硬编码的参数值),并且你在浪费大量有用的内存,这些内存在SQL Server里可以被其他组件使用。缓存的目的应该是持续数次的高重用,特定SQL语句不属于这个情况。
计划稳定性
如果你参数话你的SQL语句,或者使用存储过程。在那个情况下,SQL Server可以非常容易的重用执行计划。但是即使重用执行计划也会带来性能的问题。比如SQL Server为一个查询编译了一个需要执行书签查找的执行计划,因为用到的非聚集索引没有覆盖到查询字段。

在第8周我们说过,如果你从表获取少量数据,书签查找还是有用的。当你越过临界点时,使用全表/索引扫描将更高效。但是SQL Server如果重用缓存的执行计划,就不会考虑这个选择了——SQL Server只会盲目的重用你的计划——即使性能非常糟糕!我们看看下面的实际执行计划:

这里SQL Server盲目重用了包含书签查找的被缓存的计划。如你所见,估计行数(estimated number of rows )和实际行数(actual number of rows )完全不同。SQL Server基于假设那个查询只返回1条记录来编译和缓存了计划。但是实际上SQL Server返回了1499条记录。看看执行计划,我们会更清晰,优化器是假设只返回1条记录才执行这个操作的。
这会导致你没有计划稳定性。基于估计行数,你得到书签查找的缓存计划,要不就是如果越过临界点的话是全表/索引扫描。这个是我们在性能调优时经常碰到的性能问题。
sqLSERVER 计划缓存的更多相关文章
- SQLServer中的执行计划缓存由于长时间缓存对性能造成的干扰
本文出处:http://www.cnblogs.com/wy123/p/7190785.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- RECONFIGURE语句会清空计划缓存么?
几个星期前,有个网友问我一个非常有趣的问题:RECONFIGURE语句会清空计划缓存么?通常我对这个问题的答案是简单的是,但慢慢的我找出了真正的答案是“看情况啦”.我们来看下它,为什么“它看情况”. ...
- 谈一谈SQL Server中的执行计划缓存(下)
简介 在上篇文章中我们谈到了查询优化器和执行计划缓存的关系,以及其二者之间的冲突.本篇文章中,我们会主要阐述执行计划缓存常见的问题以及一些解决办法. 将执行缓存考虑在内时的流程 上篇文章中提到了查询优 ...
- 谈一谈SQL Server中的执行计划缓存(上)
简介 我们平时所写的SQL语句本质只是获取数据的逻辑,而不是获取数据的物理路径.当我们写的SQL语句传到SQL Server的时候,查询分析器会将语句依次进行解析(Parse).绑定(Bind).查询 ...
- 如何用参数化SQL语句污染你的计划缓存
你的SQL语句的参数化总是个好想法.使用参数化SQL语句你不会污染你的计划缓存——错!!!在这篇文章里我想向你展示下用参数化SQL语句就可以污染你的计划缓存,这是非常简单的! ADO.NET-AddW ...
- [译]SQL Server 之 查询计划缓存和重编译
查询优化是一个复杂而且耗时的操作,所以SQL Server需要重用现有的查询计划.查询计划的缓存和重用在多数情况下是有益的的,但是在某些特殊的情况下,重编译一个查询计划可能能够改善性能. SELECT ...
- 查看SQLServer各种缓存的情况
查看页面缓存: SELECT * FROM sys.dm_os_buffer_descriptors 清除页面缓存: CHECKPOINTDBCC DROPCLEANBUFFERS 查看执行计划缓存: ...
- sqlserver清除缓存(转载)
sqlserver清除缓存,记录查询时间 1 2 3 4 5 6 7 8 9 10 11 12 --1. 将当前数据库的全部脏页写入磁盘.“脏页”是已输入缓存区高速缓存且已修改但尚未写入磁盘的数据 ...
- 浅析SQL Server中的执行计划缓存(上)
简介 我们平时所写的SQL语句本质只是获取数据的逻辑,而不是获取数据的物理路径.当我们写的SQL语句传到SQL Server的时候,查询分析器会将语句依次进行解析(Parse).绑定(Bind).查询 ...
随机推荐
- [EMWIN]FRAMEWIN 与 WINDOW 的使用注意
1.对于window控件,选中这类型控件的时候直接选中对应句柄即可: WM_InvalidateWindow(hWin); WM_SelectWindow(hWin); WM_CreateTimer( ...
- Bootstrap和IE何时能相亲相爱啊~
公司新项目,嘚瑟了一下,用了用Bootstrap... ... 发现了一个小坑(也许只是对我而言)... ... 使用了2.x的Jquery,在chrome等高版本浏览器一切顺利... ... 然,3 ...
- 关于ip层的作用网址链接
http://rabbit.xttc.edu.cn/rabbit/htm/artical/201091113054.shtml
- yarn 管理nextjs 项目
预备环境 nodejs npm 1. yarn 安装 npm install -g yarn 2. nextjs 项目初始化 yarn add next react react-dom 3. 配置n ...
- yii 操作cookie
原文地址:http://blog.sina.com.cn/s/blog_664c9f650100yqkn.html 设置cookie: $cookie = new CHttpCookie('mycoo ...
- Asp.Net构架(Http请求处理流程) - Part.1
引言 我查阅过不少Asp.Net的书籍,发现大多数作者都是站在一个比较高的层次上讲解Asp.Net.他们耐心.细致地告诉你如何一步步拖放控件.设置控件属性.编写CodeBehind代码,以实现某个特定 ...
- 为什么中国出不了facebook和Twitter?
我们坐拥全球最大基数的网民,我们拥有让人骄傲的四大发明,我们有有流传全世界的孙子兵法,可是在互联网时代,我们却落后了.互联网可以说是江山人才辈辈出,各领风骚三两年. 让我们来简单地回顾一下近几年的互联 ...
- 【转】windows下mysql5.1忘记root密码解决方法
步骤如下:1.停止mysql服务(以管理员身份,在cmd命令行下运行) net stop mysql D:\>net stop mysql MySQL 服务正在停止. MySQL 服务已成功停止 ...
- FPGA中的“门”
逻辑门 在ASIC的世界里,衡量器件容量的常用标准是等效门.这是因为不同的厂商在单元库里提供了不同的功能模块,而每个功能模块的实现都要求不同数量的晶体管.这样在两个器件之间比较容量和复杂度就很困难. ...
- 2012_p1 质因数分解 (prime.cpp/c/pas)
2012_p1 质因数分解 (prime.cpp/c/pas) 时间限制: 1 Sec 内存限制: 128 MB提交: 80 解决: 27[提交][状态][讨论版][命题人:外部导入] 题目描述 ...